Metadata-Version: 2.4
Name: spendlensai
Version: 0.1.0
Summary: Python SDK for SpendLens AI.
Author: SpendLens AI
License-Expression: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# SpendLens AI Python SDK

The MVP SDK supports OpenAI chat completions and Anthropic/Claude messages. It preserves the original provider response while capturing model, token, latency, callsite, and privacy-safe prompt-template metadata for SpendLens AI.

When returned by the provider, it also captures OpenAI cached prompt tokens and Anthropic cache-read/cache-creation input tokens for the Cache Efficiency report.

Users do not need to hard-code task labels. SpendLens classifies each stable workload on the backend from its endpoint label, Python function, file path, token shape, and optional system template.

## Install Locally

```bash
pip install -e packages/spendlensai-sdk
```

## OpenAI

```python
from openai import OpenAI
from spendlensai import track

openai_client = OpenAI(api_key="OPENAI_API_KEY")

client = track(
    openai_client,
    project="shopping-assistant",
    api_key="sli_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)

def recommend_products(shopping_request: str):
    with client.tag():
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": "You are an online shopping assistant. Recommend three products that match the shopper's budget, preferences, and intended use. Give one concise reason for each recommendation."},
                {"role": "user", "content": shopping_request},
            ],
        )
    return response.choices[0].message.content
```

## Anthropic / Claude

```python
from anthropic import Anthropic
from spendlensai import track

anthropic_client = Anthropic(api_key="ANTHROPIC_API_KEY")

client = track(
    anthropic_client,
    project="shopping-assistant",
    api_key="sli_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)

def recommend_products(shopping_request: str):
    with client.tag():
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=300,
            system="You are an online shopping assistant. Recommend three products that match the shopper's budget, preferences, and intended use. Give one concise reason for each recommendation.",
            messages=[{"role": "user", "content": shopping_request}],
        )
    return response.content[0].text
```

## Optional Labels

Add a stable business endpoint when useful:

```python
with client.tag(endpoint="recommend-products"):
    response = client.chat.completions.create(...)

with client.tag(endpoint="recommend-products"):
    response = client.messages.create(...)
```

Advanced users can override automatic classification:

```python
with client.tag(endpoint="recommend-products", task="generation"):
    response = client.chat.completions.create(...)

with client.tag(endpoint="recommend-products", task="generation"):
    response = client.messages.create(...)
```

Task overrides are optional. Without an endpoint, the SDK captures the Python function name, file name, and call line so the backend can form a stable workload key.

## Metadata

```python
with client.tag(endpoint="recommend-products", metadata={"shopper_tier": "plus"}):
    response = client.chat.completions.create(...)
```

Nested tags are supported. Inner endpoint, task, and metadata values take precedence.

## Cache Efficiency

No manual cache calculation is needed for normal SDK calls. SpendLens reads:

- OpenAI: `usage.prompt_tokens_details.cached_tokens`
- Anthropic: `usage.cache_read_input_tokens` and `usage.cache_creation_input_tokens`

Run the deterministic local ingestion example with a test key:

```powershell
$env:SPENDLENS_API_KEY="sli_test_xxx..."
$env:SPENDLENS_API_BASE_URL="http://localhost:8000"
python examples/cache_efficiency_test.py
```

Then open `/dashboard/reports/cache-efficiency`. If provider responses do not contain cache fields, the report explicitly says cache metrics are unavailable; it never invents cache values.

## Prompt Privacy

`prompt_sampling="template_only"` is the default:

```python
client = track(
    openai_client,
    project="shopping-assistant",
    api_key="sli_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    prompt_sampling="template_only",
)
```

- `off`: sends no prompt content.
- `template_only`: sends only OpenAI system messages or Anthropic's `system` argument.
- `redacted_sample`: reserved for richer redaction; the MVP still sends only safe template content.

Full user messages and full message arrays are never sent by default. Prompt content and API keys are never written to SDK logs.

## Configuration

```text
SPENDLENS_API_KEY=sli_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SPENDLENS_PROJECT=shopping-assistant
SPENDLENS_API_BASE_URL=https://api.spendlensai.dev
SPENDLENS_DISABLE=0
```

Use `api_base_url="http://localhost:8000"` for local development. Call `client.flush()` when an event batch must be sent immediately.

Set `SPENDLENS_DISABLE=1` to return the original OpenAI or Anthropic client unchanged and disable all tracking and SpendLens network calls.

## Failure Behavior

Tracking failures are silent by default and never replace a provider response. Set `debug=True` to emit generic SDK warnings without API keys or prompt content.

Streaming, proxy/gateway behavior, prompt rewriting, automatic prompt optimization, and local SQLite storage are outside the MVP.
