Metadata-Version: 2.4
Name: abto
Version: 0.0.1
Summary: ABTO server-side SDK for Python — gateway baseURL + x-abto-* header injection via contextvars and httpx event hooks.
Project-URL: Homepage, https://github.com/greedy-co/abto
Project-URL: Issues, https://github.com/greedy-co/abto/issues
License-Expression: MIT
Keywords: abto,analytics,autocapture,llm,observability
Requires-Python: >=3.9
Provides-Extra: httpx
Requires-Dist: httpx>=0.24; extra == 'httpx'
Provides-Extra: openai
Requires-Dist: httpx>=0.24; extra == 'openai'
Requires-Dist: openai>=1.0; extra == 'openai'
Description-Content-Type: text/markdown

# abto (Python)

ABTO server-side SDK for Python. 얇은 gateway 헤더 helper로, `contextvars`로 `x-abto-*` 식별자를 운반하고 `httpx` event hook으로 outbound provider 호출에 주입한다. token·cost·latency·`request_id`·variant는 gateway가 소유한다.

`@abto-app/sdk/server`(Node)의 Python 대응이다. npm과 PyPI는 다른 레지스트리라 언어별로 분리 배포한다.

## Install

```bash
pip install abto                 # 코어(contextvars 헤더 helper)
pip install "abto[openai]"       # openai + httpx 통합까지
```

## Quick Start

```python
from abto import create_abto

abto = create_abto(
    api_key="ABTO_API_KEY",
    gateway_base_url="https://gateway.abto.ai/v1",
)
openai = abto.openai()  # base_url=gateway + 요청마다 x-abto-* 주입

def generate(user_id: str, trace_id: str):
    with abto.with_context(user_id=user_id, node_id="resume.make", trace_id=trace_id):
        return openai.chat.completions.create(
            model="gpt-4.1",
            messages=[{"role": "user", "content": "Create a resume draft"}],
        )
```

## httpx 직접 사용

```python
import httpx
from abto import abto_request_hook, with_context

client = httpx.Client(event_hooks={"request": [abto_request_hook()]})

with with_context(user_id="u1", node_id="resume.make"):
    client.post("https://gateway.abto.ai/v1/...")  # x-abto-* 자동 첨부
```

## Public API

- `create_abto(api_key=None, gateway_base_url=None) -> Abto`
- `abto.openai(**kwargs)` — gateway baseURL + 헤더 주입된 OpenAI client (extra: `openai`)
- `abto.with_context(user_id=?, node_id=?, trace_id=?)` — 요청 단위 context (context manager)
- `abto.get_headers(ctx=None)` / `abto.create_trace_id()` / `abto.httpx_event_hooks()`
- 하위 helper: `with_context`, `get_context`, `set_context`, `get_headers`, `create_trace_id`, `create_traceparent`, `abto_request_hook`, `ABTO_HEADER`, `AbtoContext`

## Header Contract

```text
x-abto-device-id     (required)
x-abto-node-key     (required; "feature.node" dot notation, e.g. resume.make)
traceparent        (trace_id; gateway-deferred in Round1)
```

Gateway는 API key를 `tenant_id`로 매핑하고 `request_id`(응답 `x-request-id`)를 발급하며 `variant_id`를 배정하고, provider 전달 전 `x-abto-*`를 strip한다.

## Test

```bash
pip install pytest && pytest
```
