Metadata-Version: 2.4
Name: apipurse-sdk
Version: 0.1.0
Summary: APIPurse real-time cost tracking SDK for Python — automatic OpenAI/Anthropic wrappers plus a manual track_completion() client. Not a network proxy: nothing routes through APIPurse's servers.
Author: APIPurse
License: MIT
Project-URL: Homepage, https://github.com/yelmorab/Apipurse
Keywords: apipurse,openai,anthropic,cost-tracking,llm
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# APIPurse SDK — Python

Python port of `sdk/apipurse-sdk` (the TypeScript reference implementation).
Dependency-free (standard library only) client for `/api/track/completion` —
the real-time tracking endpoint. Verified end-to-end in this repo's sandbox
against fake OpenAI/Anthropic-shaped clients (streaming + non-streaming).

Two integration styles, both call the same endpoint under the hood:

- **Automatic** (`wrap_openai()` / `wrap_anthropic()`) — wrap your existing
  client once at setup; every subsequent `.create()` call is tracked with
  zero changes at each call site. Works with both sync and async clients
  (`OpenAI`/`AsyncOpenAI`, `Anthropic`/`AsyncAnthropic`) — detected
  automatically.
- **Manual** (`APIPurse.track_completion()`) — call it yourself right after
  a completion.

Neither is a network proxy: no request or response data is ever routed
through APIPurse's servers. Only the model ID and token counts are sent.

## Install

Not yet published to PyPI. Copy the `apipurse/` folder into your project, or:

```bash
pip install -e /path/to/sdk-python
```

## Usage

```python
import os
from openai import OpenAI
from apipurse import APIPurse, wrap_openai

apipurse = APIPurse(
    ingest_token=os.environ["APIPURSE_INGEST_TOKEN"],
    provider_id=os.environ["APIPURSE_PROVIDER_ID"],
    base_url="https://your-apipurse-domain.com",
)

client = wrap_openai(OpenAI(), apipurse)

# Tracked automatically:
completion = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)
```

For Anthropic:

```python
from anthropic import Anthropic
from apipurse import wrap_anthropic

client = wrap_anthropic(Anthropic(), apipurse)
message = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
)
```

Manual path (any provider, any call shape):

```python
result = apipurse.track_completion(
    model="gpt-4o", input_tokens=120, output_tokens=48,
)
```

## Publishing to PyPI

Ships as plain source. To publish: add a `[project]` `version` bump
workflow, then `python -m build && twine upload dist/*`. Needs a PyPI
account/org you control — not done here.
