Metadata-Version: 2.4
Name: onstoa
Version: 0.2.11
Summary: Business telemetry and payments SDK for AI products
Project-URL: Homepage, https://onstoa.com
Project-URL: Repository, https://github.com/stoa-org/stoa
Project-URL: Documentation, https://docs.onstoa.com
Author-email: Stoa <hello@stoa.dev>
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25.0
Requires-Dist: orjson>=3.9.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: tenacity>=8.0.0
Requires-Dist: uuid-utils>=0.6.0
Provides-Extra: all
Requires-Dist: anthropic>=0.18.0; extra == 'all'
Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'all'
Requires-Dist: elevenlabs>=1.0.0; extra == 'all'
Requires-Dist: openai>=1.0.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.18.0; extra == 'anthropic'
Provides-Extra: claude-agent
Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'claude-agent'
Provides-Extra: dev
Requires-Dist: anthropic>=0.18.0; extra == 'dev'
Requires-Dist: elevenlabs>=1.0.0; extra == 'dev'
Requires-Dist: openai>=1.0.0; extra == 'dev'
Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.5.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: ty>=0.0.7; extra == 'dev'
Provides-Extra: elevenlabs
Requires-Dist: elevenlabs>=1.0.0; extra == 'elevenlabs'
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == 'openai'
Description-Content-Type: text/markdown

# Stoa Python SDK

Business telemetry and payments for AI products.

Stoa instruments native AI provider clients, attaches your application's
`user_id`, and helps you understand which users, features, and product areas are
driving AI usage, cost, and outcomes.

## Installation

```bash
pip install onstoa
```

## Quick Start

```python
from openai import OpenAI
from stoa import Stoa

stoa = Stoa()

# Idempotently create or update the user profile in Stoa.
stoa.identify(
    user_id=user.id,
    metadata={"plan": "pro"},
)

# Build the native provider client in your app, then wrap it with Stoa.
openai = stoa.openai(
    OpenAI(timeout=30),
    user_id=user.id,
)


@stoa.context(feature="summary_export", product="docs")
def generate_summary(document: str):
    response = openai.responses.create(
        model="gpt-4.1-mini",
        input=f"Summarize this document:\n\n{document}",
    )

    stoa.track(
        "summary_export.completed",
        user_id=user.id,
        metadata={"format": "pdf"},
    )

    return response
```

## Identify Users

Call `identify` when a user signs up, logs in, or when you want to sync stable
user metadata.

```python
stoa.identify(
    user_id="user_123",
    metadata={
        "plan": "enterprise",
        "workspace_id": "ws_456",
    },
)
```

`identify` is idempotent. It creates the user profile if it does not exist and
updates metadata if it does. It does not set active identity; provider
instrumentation and custom events still require an explicit `user_id`.

## Instrument AI Providers

Construct provider clients exactly as you would without Stoa, then pass them to
Stoa.

```python
from openai import OpenAI

openai = stoa.openai(
    OpenAI(api_key="sk-...", timeout=30, max_retries=2),
    user_id=user.id,
)
```

Every provider call made through the returned client is attributed to that
`user_id`.

### OpenAI

```python
openai = stoa.openai(OpenAI(), user_id=user.id)

response = openai.responses.create(
    model="gpt-4.1-mini",
    input="Write a release note",
)
```

### Anthropic

```python
from anthropic import Anthropic

anthropic = stoa.anthropic(Anthropic(), user_id=user.id)

message = anthropic.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a release note"}],
)
```

### ElevenLabs

```python
from elevenlabs.client import ElevenLabs

elevenlabs = stoa.elevenlabs(ElevenLabs(), user_id=user.id)

audio = elevenlabs.text_to_speech.convert(
    voice_id="JBFqnCBsd6RMkjVDRZzb",
    model_id="eleven_multilingual_v2",
    text="Welcome back",
)
```

### OpenRouter

```python
openrouter = stoa.openrouter(
    OpenAI(
        api_key=os.environ["OPENROUTER_API_KEY"],
        base_url="https://openrouter.ai/api/v1",
    ),
    user_id=user.id,
)
```

## Add Context

Use `context` to attach feature, product, workflow, experiment, or route
metadata to work done inside a scope.

```python
with stoa.context(feature="chat", product="assistant"):
    openai.responses.create(...)
```

`context` can also be used as a decorator.

```python
@stoa.context(feature="summary_export", product="docs")
def generate_summary(document: str):
    return openai.responses.create(
        model="gpt-4.1-mini",
        input=document,
    )
```

Nested context merges automatically. Inner values override outer values.

## Track Custom Events

Use `track` for product or business events Stoa cannot infer from provider
calls.

```python
stoa.track(
    "report.exported",
    user_id=user.id,
    metadata={
        "format": "csv",
        "rows": 1200,
    },
)
```

Tracked events inherit active `context` metadata.

## Create Payments

Use `create_payment` when you want to start a Stripe payment flow for a user.

```python
payment = stoa.create_payment(
    user_id=user.id,
    email=user.email,
    return_url="https://app.example.com/billing/return",
)

redirect_user_to(payment.checkout_url)
```

## Billing Webhooks

Stoa's SDK does not block AI provider calls by default.

Use webhooks to react to billing events such as:

```text
balance.low
balance.depleted
payment.succeeded
payment.failed
subscription.updated
```

Your app decides what to do when those events arrive, such as notifying the
user, prompting for payment, or changing access.

## Environment Variables

```bash
STOA_API_KEY=...
STOA_BASE_URL=https://www.onstoa.com/api
```
