margindash 1.1.6
MarginDash SDK for tracking AI usage and revenue
Requires Python: >=3.10

# MarginDash Python SDK

Track AI usage and revenue with [MarginDash](https://margindash.com).

## Installation

```bash
pip install margindash
```

## Quick Start

```python
from openai import OpenAI
from margindash import MarginDash

openai = OpenAI()
md = MarginDash(api_key="md_live_...")

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

md.add_usage(
    vendor="openai",
    model=response.model,
    input_tokens=response.usage.prompt_tokens,
    output_tokens=response.usage.completion_tokens,
)
md.track(customer_id=user.id, event_type="summarize")

# Events are automatically flushed in the background.
# Before your process exits:
md.shutdown()
```

Only the model name and token counts are sent to MarginDash — no request
or response content ever leaves your infrastructure.

## Tracking events

Record usage from each AI API call with `add_usage()`, then call
`track()` to flush them into an event.

### `track()` fields

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `customer_id` | `str` | **yes** | — | Your customer identifier |
| `revenue_amount_in_cents` | `int` | no | `None` | Revenue for this event in cents |
| `event_type` | `str` | no | `"ai_request"` | Category for this event |
| `unique_request_token` | `str` | no | auto-generated UUID | Idempotency key |
| `occurred_at` | `str` | no | current time (ISO 8601) | When the event occurred |

### `add_usage()` fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `vendor` | `str` | **yes** | AI vendor name — e.g. `"openai"`, `"anthropic"` |
| `model` | `str` | **yes** | AI model name |
| `input_tokens` | `int` | **yes** | Input/prompt token count |
| `output_tokens` | `int` | **yes** | Output/completion token count |

### Examples

```python
# Single call
r1 = openai.chat.completions.create(model="gpt-4o", messages=messages)
md.add_usage(
    vendor="openai",
    model=r1.model,
    input_tokens=r1.usage.prompt_tokens,
    output_tokens=r1.usage.completion_tokens,
)
md.track(customer_id=user.id, event_type="summarize")

# With revenue
md.track(customer_id=user.id, event_type="summarize", revenue_amount_in_cents=500)

# Agent session with multiple AI calls
r2 = openai.chat.completions.create(model="gpt-4o", messages=messages)
md.add_usage(
    vendor="openai",
    model=r2.model,
    input_tokens=r2.usage.prompt_tokens,
    output_tokens=r2.usage.completion_tokens,
)

r3 = anthropic.messages.create(model="claude-3-opus-20240229", messages=messages)
md.add_usage(
    vendor="anthropic",
    model=r3.model,
    input_tokens=r3.usage.input_tokens,
    output_tokens=r3.usage.output_tokens,
)

r4 = google.generate_content(model="gemini-1.5-pro", contents=contents)
md.add_usage(
    vendor="gemini",
    model="gemini-1.5-pro",
    input_tokens=r4.usage_metadata.prompt_token_count,
    output_tokens=r4.usage_metadata.candidates_token_count,
)

md.track(customer_id=user.id, event_type="agent_session", revenue_amount_in_cents=1200)
```

### Supported vendors

The following vendor names are supported: `openai`, `anthropic`, `gemini`,
`groq`, `azure`, `bedrock`. The vendor name and model must match a vendor
rate configured in your MarginDash account.

## Configuration

```python
MarginDash(
    api_key="md_live_...",              # required
    base_url="https://...",             # default: https://margindash.com/api/v1
    flush_interval=5.0,                 # default: 5.0 seconds
    max_retries=3,                      # default: 3
    default_event_type="ai_request",    # default: "ai_request"
    on_error=lambda err: print(err.message),  # optional error callback
)
```

## Manual Flush and Shutdown

Call `shutdown()` before your application exits to ensure all buffered
events are sent. The SDK also registers an `atexit` handler as a safety
net, but explicit shutdown is recommended:

```python
md = MarginDash(api_key="md_live_...")
try:
    md.add_usage(vendor="openai", model="gpt-4o", input_tokens=100, output_tokens=50)
    md.track(customer_id=user.id)
    md.flush()   # flush immediately if needed
finally:
    md.shutdown()
```

## License

MIT