> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.meshapi.ai/docs/sd-ks/llms.txt.
> For full documentation content, see https://developers.meshapi.ai/docs/sd-ks/llms-full.txt.

# Python SDK

> Getting started with the MeshAPI Python SDK.

# Python SDK

The MeshAPI Python SDK provides a native, typed client for integrating the AI model gateway into your Python 3 applications.

## Requirements

* Python ≥ 3.9
* `httpx` ≥ 0.27
* `pydantic` ≥ 2.0

## Installation

```bash
pip install meshapi-python-sdk
```

## Quick Start

You can interact with MeshAPI using either a synchronous or asynchronous client.
We strongly suggest using one client instance per authentication realm (Data-Plane vs Control-Plane).

### Synchronous Client

```python
from meshapi import MeshAPI, ChatCompletionParams, ChatMessage

# Initialize the client with your data-plane API key
client = MeshAPI(base_url="https://api.meshapi.ai", token="rsk_...")

# Non-streaming request
resp = client.chat.completions.create(
    ChatCompletionParams(
        model="openai/gpt-4o-mini",
        messages=[ChatMessage(role="user", content="What is 2+2?")],
    )
)
print(resp.choices[0].message.content)

# Streaming request
for chunk in client.chat.completions.stream(
    ChatCompletionParams(
        model="openai/gpt-4o-mini",
        messages=[ChatMessage(role="user", content="Count to 5.")],
    )
):
    if chunk.choices and chunk.choices[0].delta:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

### Asynchronous Client

```python
import asyncio
from meshapi import AsyncMeshAPI, ChatCompletionParams, ChatMessage

async def main():
    async with AsyncMeshAPI(base_url="https://api.meshapi.ai", token="rsk_...") as client:
        resp = await client.chat.completions.create(
            ChatCompletionParams(
                model="openai/gpt-4o-mini",
                messages=[ChatMessage(role="user", content="Hello!")],
            )
        )
        print(resp.choices[0].message.content)

asyncio.run(main())
```

## Error Handling & Retries

The client automatically retries `GET` and non-streaming `POST`/`PATCH` requests on status codes `429`, `502`, `503`, and `504` with exponential backoff.

If an error occurs, a `MeshAPIError` is raised:

```python
from meshapi import MeshAPIError

try:
    resp = client.chat.completions.create(...)
except MeshAPIError as e:
    print(e.status)               # HTTP status code
    print(e.error_code)           # "rate_limit_exceeded", "unauthorized", etc.
    print(e.request_id)           # Traceable request ID
    print(e.retry_after_seconds)  # Present on 429 errors
```

> \[!WARNING]
> **Streams do not automatically retry!** If a connection drops mid-stream, the SDK raises a `MeshAPIError` with `error_code="stream_interrupted"`. You must catch this and restart the request manually if required.