Metadata-Version: 2.5
Name: pawa-ai
Version: 0.2.0
Summary: Official Python SDK for the Pawa AI API
Project-URL: Homepage, https://pawa-ai.com
Project-URL: Documentation, https://docs.pawa-ai.com
Project-URL: Repository, https://github.com/Sartify/pawa-ai-python
Project-URL: Issues, https://github.com/Sartify/pawa-ai-python/issues
Author-email: Sartify Company Limited <hello@sartify.co.tz>
License-Expression: MIT
License-File: LICENSE
Keywords: africa,ai,chat,embeddings,llm,pawa-ai,sdk
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.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.6.0; extra == 'dev'
Description-Content-Type: text/markdown

# Pawa AI Python SDK

[![CI](https://github.com/Sartify/pawa-ai-python/actions/workflows/ci.yml/badge.svg)](https://github.com/Sartify/pawa-ai-python/actions/workflows/ci.yml)

Official Python library for the [Pawa AI API](https://docs.pawa-ai.com).

Pawa AI provides African-built small language models for chat, voice, embeddings, document parsing, agents, and knowledge bases.

## Installation

```bash
pip install pawa-ai
```

## Quickstart

Set your API key:

```bash
export PAWA_AI_API_KEY="your_api_key_here"
```

Get your key from the [Builders Dashboard](https://builder.pawa-ai.com/dashboard?page=keys).

### Chat

```python
from pawa_ai import PawaAI

client = PawaAI()

response = client.chat.create(
    model="pawa-v1-ember-20240924",
    messages=[
        {
            "role": "user",
            "content": [{"type": "text", "text": "Hello! How can I use AI in my app?"}],
        }
    ],
    stream=False,
)

print(response.text)  # typed ChatCompletion response
print(response.usage)  # token usage when available
```

### Streaming

```python
with client.chat.create(
    model="pawa-v1-ember-20240924",
    messages=[
        {"role": "user", "content": [{"type": "text", "text": "Explain RAG in simple terms"}]}
    ],
    stream=True,
) as stream:
    for delta in stream.text_deltas():
        print(delta, end="", flush=True)

    # Or collect the full response after streaming
    completion = stream.collect()
    print(completion.text)
```

Async streaming:

```python
stream = await client.chat.create(..., stream=True)
text = await stream.collect_text()
```

### Text-to-Speech

```python
audio = client.voice.text_to_speech.create(
    model="pawa-tts-v1-20250704",
    text="Hello, this is Pawa AI speaking!",
    voice="liora",
)

with open("output.mp3", "wb") as f:
    f.write(audio)
```

### Embeddings

```python
response = client.vectors.create(
    model="pawa-embeddings-v1-20241001",
    sentences=["Embed this sentence.", "And this one too."],
    lang="multi",
)

embeddings = response.embeddings
```

Pass `raw=True` on any resource method to get the original JSON dict instead of typed models.

### Retries with exponential backoff

```python
from pawa_ai import PawaAI, RetryConfig

client = PawaAI(
    retry_config=RetryConfig(
        max_retries=3,
        initial_delay=0.5,
        max_delay=8.0,
        exponential_base=2.0,
        jitter=0.1,
    )
)
```

Retries automatically apply to rate limits (429), server errors (500/502/503/504), and connection failures. The SDK respects `Retry-After` response headers when present.

### Async

```python
import asyncio
from pawa_ai import AsyncPawaAI

async def main():
    async with AsyncPawaAI() as client:
        response = await client.chat.create(
            model="pawa-v1-ember-20240924",
            messages=[
                {"role": "user", "content": [{"type": "text", "text": "Habari yako?"}]}
            ],
        )
        print(response["data"])

asyncio.run(main())
```

## API coverage

| Resource | Methods |
|----------|---------|
| `client.chat` | `create`, `completions` |
| `client.models` | `list`, `retrieve` |
| `client.voice.text_to_speech` | `create` |
| `client.voice.speech_to_text` | `create`, `transcribe` |
| `client.vectors` | `create`, `embeddings` |
| `client.documents` | `parse` |
| `client.agents` | `create`, `update`, `delete`, `list`, `retrieve` |
| `client.agents.chat` | `create` |
| `client.storage.knowledge_base` | CRUD, `list_files`, `semantic_retrieval` |
| `client.transcribe.workspaces` | CRUD, transcription management |

## Error handling

```python
from pawa_ai import PawaAI, AuthenticationError, RateLimitError, ChatCompletion

client = PawaAI()

try:
    completion: ChatCompletion = client.chat.create(model="pawa-v1-ember-20240924", messages=[...])
except AuthenticationError as e:
    print(f"Auth failed: {e.message}")
except RateLimitError as e:
    print(f"Rate limited: {e.status_code}")
```

## Documentation

- [Pawa AI Docs](https://docs.pawa-ai.com)
- [API Reference](https://docs.pawa-ai.com/api-reference/introduction)
- [Quickstart Guide](https://docs.pawa-ai.com/get-started/quickstart)

## License

MIT
