Metadata-Version: 2.4
Name: pyai-sdk
Version: 0.1.0
Summary: Official Python SDK for the PyAI API (Hear, Speak, Cue, Omni).
Project-URL: Homepage, https://pyai.com
Project-URL: Documentation, https://api.pyai.com/docs
Project-URL: Repository, https://github.com/atomsai/pyai-platform-backend
License: MIT
Keywords: openai-compatible,pyai,speech,stt,tts,voice-ai
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# pyai-sdk (Python SDK)

Official Python SDK for the [PyAI API](https://api.pyai.com) — Hear
(speech-to-text), Speak (text-to-speech + cloning), Cue (turn detection + KB
context), and Omni (realtime voice agents). Zero third-party dependencies
(standard library only); Python 3.9+.

The contract is `https://api.pyai.com/openapi.json`. This SDK wraps it with
typed errors, automatic retries, and realtime URL helpers.

## Install

```bash
pip install pyai-sdk
```

## Quickstart

```python
import os
from pyai import PyAI, new_idempotency_key

pyai = PyAI(api_key=os.environ["PYAI_API_KEY"])

# Text-to-speech
audio = pyai.audio.speech(input="Hello from PyAI.", voice="stock_sarah_style2")
open("hello.wav", "wb").write(audio)

# Voices
voices = pyai.voices.list(gender="female")

# Async transcription (safe retry with an idempotency key)
job = pyai.transcription_jobs.create(
    audio_url="https://example.com/call.wav",
    diarize=True,
    idempotency_key=new_idempotency_key(),
)
done = pyai.transcription_jobs.get(job["job_id"])
```

## Realtime (Omni)

Keys travel as a WebSocket subprotocol. Use the helpers with your preferred WS
library (e.g. `websockets`):

```python
url = pyai.realtime_url(product="omni", agent_id="agent_123")
subprotocol = pyai.realtime_subprotocol()

import asyncio, websockets

async def main():
    async with websockets.connect(url, subprotocols=[subprotocol]) as ws:
        async for frame in ws:
            print(frame)

asyncio.run(main())
```

> Omni uses the native `wss://api.pyai.com/v1/omni` surface (the default for
> `product="omni"`); `product="flow"` uses `/v1/realtime`. The older
> `/v2/omni/chat` URL is deprecated but still works.

## Errors

Failures raise `PyAIError` with a stable `code` (branch on it, not the message):

```python
from pyai import PyAIError

try:
    pyai.audio.speech(input="hi")
except PyAIError as err:
    if err.code == "credit_exhausted":
        ...  # out of prepaid credit — add credit or use a sandbox key
```

Common codes: `unauthorized`, `forbidden`, `credit_exhausted`,
`rate_limit_exceeded`, `concurrency_limit_exceeded`, `idempotency_conflict`.
`429`/`5xx` are retried automatically (honoring `Retry-After`); tune with
`PyAI(api_key, max_retries=...)`.

## Develop

```bash
python -m unittest discover -s tests -v   # no network; transport injected
```
