Metadata-Version: 2.4
Name: pumpsdk
Version: 0.2.0
Summary: Drop-in OpenAI-compatible Python SDK for the Pump LLM gateway
Author-email: "Pump.co" <support@pump.co>
License: MIT
Project-URL: Homepage, https://pump.co
Project-URL: Repository, https://github.com/pumpcard/pump-sdk
Project-URL: Issues, https://github.com/pumpcard/pump-sdk/issues
Keywords: pump,openai,llm,gateway,api,client
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Dynamic: license-file

# pump Python SDK

A **drop-in replacement for the official [OpenAI Python SDK](https://github.com/openai/openai-python)** for [pump](https://pump.co) — a multi-tenant LLM gateway that exposes an **OpenAI-compatible** API.

Keep your existing OpenAI request code exactly as-is. The only things that change are the **import**, the **`base_url`**, and using your **pump key** (`pk-...`) as the API key.

## Installation

```bash
pip install pumpsdk
```

The distribution is published as `pumpsdk`; the import package is `pump`.

## Quickstart — OpenAI drop-in

```python
# before:
# from openai import OpenAI
# client = OpenAI()

from pump.openai import OpenAI

client = OpenAI(
    base_url="https://api.pump.co/ai/v1",
    api_key="pk-...",  # your pump key (or set PUMP_API_KEY)
)

resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)

print(resp.choices[0].message.content)
```

That's the whole migration. Every standard parameter (`temperature`, `tools`,
`tool_choice`, `response_format`, `seed`, `stream`, ...) is forwarded to the
gateway unchanged.

`Pump` is the same client under a more obvious name — `from pump import Pump` and
`from pump.openai import OpenAI` are interchangeable.

### API key

Pass `api_key="pk-..."` explicitly, or omit it and the SDK reads `PUMP_API_KEY`
from the environment:

```bash
export PUMP_API_KEY="pk-..."
```

```python
from pump.openai import OpenAI

client = OpenAI()  # base_url defaults to https://api.pump.co/ai/v1
```

## Responses & embeddings

```python
client.responses.create(model="gpt-4o-mini", input="Write a haiku about pumps.")

client.embeddings.create(model="text-embedding-3-small", input="hello world")
```

## Streaming

The streamed object is iterable directly — no context manager required:

```python
stream = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Count to 5"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta
    if getattr(delta, "content", None):
        print(delta.content, end="", flush=True)
```

You can also use it as a context manager to guarantee the connection closes:

```python
with client.chat.completions.create(..., stream=True) as stream:
    for chunk in stream:
        ...
```

## Async

```python
import asyncio
from pump.openai import AsyncOpenAI

async def main():
    client = AsyncOpenAI(api_key="pk-...")

    resp = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Hello!"}],
    )
    print(resp.choices[0].message.content)

    # async streaming
    stream = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Count to 5"}],
        stream=True,
    )
    async for chunk in stream:
        ...

    await client.aclose()

asyncio.run(main())
```

## Attaching metadata & tags (pump extension)

pump lets you attach observability metadata and tags to any request. These are
**not** part of the OpenAI request body — sending custom fields there would be
rejected by the upstream provider. Instead, pass them as explicit kwargs and the
SDK sends them as gateway headers (`x-pump-metadata`, `x-pump-tags`), which the
gateway reads and strips before forwarding the request upstream.

```python
resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
    metadata={"user_id": "u_123", "feature": "support-bot"},
    tags=["prod", "support"],
)
```

You can also pass arbitrary headers via `extra_headers`:

```python
client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[...],
    extra_headers={"x-pump-trace-id": "abc123"},
)
```

> Note: OpenAI's own body-level `metadata` field (for stored completions) is a
> different thing. If you need it, pass it through `extra_body={"metadata": {...}}`.

## Response objects

Responses support **both** attribute access and dict access, and expose
`.model_dump()` to get a plain `dict`:

```python
resp = client.chat.completions.create(...)

resp.choices[0].message.content        # attribute access
resp["choices"][0]["message"]["content"]  # dict access
resp.model_dump()                       # plain dict
```

## Error handling

The SDK raises a single error type, `pump.PumpError`. For HTTP failures it
carries the `status_code` (and `response`) so you can branch on it:

```python
from pump import PumpError

try:
    client.chat.completions.create(...)
except PumpError as e:
    if e.status_code == 429:
        ...  # rate limited
    elif e.status_code == 401:
        ...  # bad API key
    else:
        raise
```

## Roadmap: more providers

The SDK is built on a shared transport so additional provider shims can be added
without changing existing code. An Anthropic-compatible shim
(`from pump.anthropic import Anthropic`) is reserved as an extension point and
will land once the gateway exposes an Anthropic-compatible endpoint.

## Development

```bash
pip install -e ".[dev]"
pytest
```

Tests use `httpx.MockTransport` and never call the real API.

## License

MIT
