Metadata-Version: 2.4
Name: yesil-health-ai-api
Version: 0.1.1
Summary: Official Python client for the Yesil Health AI enterprise (B2B) API.
Project-URL: Homepage, https://yesilhealth.com
Author: Yesil Health
License: MIT
License-File: LICENSE
Keywords: ai,health,medical,sse,yesil
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Description-Content-Type: text/markdown

# yesil-health-ai-api (Python)

Official Python client for the **Yesil Health AI enterprise (B2B) API**.

Synchronous, built on [httpx](https://www.python-httpx.org/). The hard part of
integrating — parsing the typed Server-Sent Events stream — is handled for you.
Mirror of the TypeScript client `@yesilsci/health-ai-api`.

## Install

```bash
pip install yesil-health-ai-api
```

## Quick start

```python
import uuid
from yesil_health import YesilHealthClient

client = YesilHealthClient(
    base_url="https://api.yesilhealth.com",
    api_key="...",  # sent as X-API-Key
)

for ev in client.chat_stream({
    "question": "Is metformin safe for a patient with stage 3 CKD?",
    "request_id": str(uuid.uuid4()),       # idempotent billing — recommended
    "demographics": {"age": 62, "sex": "female"},
    "health_context": "eGFR 45 mL/min/1.73m². On lisinopril 10mg daily.",
}):
    if ev["type"] == "delta":
        print(ev["content"], end="", flush=True)
```

One-shot (no live rendering):

```python
result = client.chat({"question": "..."})
print(result["text"])
```

The client is a context manager:

```python
with YesilHealthClient(base_url=..., api_key=...) as client:
    ...
```

## Authentication

Every request is authenticated with your enterprise API key via the `X-API-Key`
header. Keep it server-side; never ship it in a client app.

## The event stream

`chat_stream()` yields event dicts. Route on `event["type"]`:

| `type`             | Payload                              | Notes |
|--------------------|--------------------------------------|-------|
| `meta`             | `phase`, `conversation_id`, research preview | Lifecycle + mid-stream research previews. |
| `delta`            | `content`                            | Append to build the answer text. |
| `citation`         | citation fields                      | A literature citation. |
| `graph`            | `data`                               | Structured chart/diagram. |
| `memory_extracted` | `signals`                            | Only if your tenant has `extract_memory` enabled. |
| `done`             | `summary`                            | Terminal success event. |
| `error`            | `message`, `code`                    | Terminal failure event. |

> **Forward compatibility.** The API only ever *adds* fields and event types
> within a contract version. Always ignore unknown `type` values — this client
> yields them as plain dicts rather than raising.

## Errors

Non-2xx responses raise `YesilApiError` with `status`, `code` (server
`error_code`), and message:

```python
from yesil_health import YesilApiError

try:
    client.chat({"question": "..."})
except YesilApiError as e:
    if e.code == "RATE_LIMITED":  # 429
        ...
    if e.status == 402:           # quota exhausted / billing
        ...
```

## Account endpoints

```python
client.billing()  # billing status
client.quota()    # quota / rate-limit status
client.usage()    # usage report
```

## Versioning

Targets contract **v1** (`/api/v1`). Pass `api_version="v2"` to
`YesilHealthClient` to migrate when a new major version ships. v1 is never
force-killed. Kept in lockstep with the TypeScript client — see
`backend/sdk/CONTRACT_SYNC.md`.
