Metadata-Version: 2.4
Name: rumik
Version: 0.2.0
Summary: The official Python SDK for the Rumik Silk text-to-speech API.
Project-URL: Homepage, https://rumik.ai
Project-URL: Documentation, https://docs.rumik.ai
Project-URL: Repository, https://github.com/rumik-ai/rumik-python
Author: Rumik AI
License-Expression: MIT
License-File: LICENSE
Keywords: audio,rumik,silk,speech,text-to-speech,tts,voice
Classifier: Development Status :: 4 - Beta
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 :: Multimedia :: Sound/Audio :: Speech
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.23.0
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: ws
Requires-Dist: websockets>=13.0; extra == 'ws'
Description-Content-Type: text/markdown

# Rumik Python SDK

The official Python SDK for the [Rumik Silk](https://docs.rumik.ai) text-to-speech API.

Turn text into natural, expressive speech with a few lines of code.

## Installation

```bash
pip install rumik
```

Real-time WebSocket streaming needs an extra dependency:

```bash
pip install "rumik[ws]"
```

## Quickstart

```python
from rumik import Rumik

client = Rumik(api_key="rk_live_...")  # or set the RUMIK_API_KEY env var

audio = client.speech.create(
    text="[happy] Namaste! Kaise hain aap?",
    model="muga",
)
audio.save("hello.wav")
```

### Controlling the voice (mulberry model)

```python
audio = client.speech.create(
    text="Hi there, how can I help you today?",
    model="mulberry",
    description="a warm 30s female voice, smooth timbre, conversational pacing",
    speaker="speaker_2",
)
audio.save("greeting.wav")
```

### Async

For servers and high-concurrency workloads, use `AsyncRumik` with `async`/`await`:

```python
import asyncio
from rumik import AsyncRumik

async def main():
    async with AsyncRumik() as client:  # reads RUMIK_API_KEY
        audio = await client.speech.create(text="Hello!", model="mulberry")
        audio.save("hello.wav")

asyncio.run(main())
```

Fire many requests concurrently with `asyncio.gather`:

```python
async with AsyncRumik() as client:
    clips = await asyncio.gather(
        client.speech.create(text="One"),
        client.speech.create(text="Two"),
        client.speech.create(text="Three"),
    )
```

### Real-time streaming

For voice agents and low-latency playback, stream PCM audio over a WebSocket as
it is generated. Requires the `websockets` extra (`pip install "rumik[ws]"`).

```python
from rumik import Rumik

client = Rumik()
with client.speech.stream(text="Streaming in real time.", model="mulberry") as stream:
    for chunk in stream:        # raw PCM (24 kHz mono 16-bit) as it arrives
        play(chunk)             # feed your audio device

# After the stream ends:
print(stream.request_id, stream.credits_used)
```

Save a stream straight to a playable WAV file:

```python
with client.speech.stream(text="Hello!", model="mulberry") as stream:
    stream.save("out.wav")
```

Async streaming mirrors this with `async with` / `async for`:

```python
async with AsyncRumik() as client:
    async with client.speech.stream(text="Hello!") as stream:
        async for chunk in stream:
            await play(chunk)
```

The SDK handles the two-step handshake (minting a session token, then opening
the WebSocket) for you — you just iterate audio.

## Models

| Model      | Steering                                              |
| ---------- | ----------------------------------------------------- |
| `muga`     | Expressive. Prefix text with a tone tag, e.g. `[happy]`. |
| `mulberry` | Faster. Use a natural-language `description` + `speaker`. |

Tone tags for `muga`: `neutral`, `happy`, `sad`, `excited`, `angry`, `whisper`.

## Configuration

```python
client = Rumik(
    api_key="rk_live_...",   # falls back to RUMIK_API_KEY
    timeout=60.0,            # per-request timeout (seconds)
    max_retries=2,           # automatic retries on 429 / 5xx / network errors
)
```

## Error handling

```python
from rumik import Rumik, RateLimitError, AuthenticationError, APIStatusError

client = Rumik()
try:
    audio = client.speech.create(text="Hello")
except AuthenticationError:
    print("Check your API key.")
except RateLimitError as e:
    print(f"Slow down. Retry after {e.retry_after}s.")
except APIStatusError as e:
    print(f"API error {e.status_code}: {e}")
```

## Audio format

Rumik Silk returns 24 kHz, mono, signed 16-bit PCM. The HTTP API wraps it in a
WAV container, so `audio.save("out.wav")` produces a ready-to-play file.

## License

MIT
