Metadata-Version: 2.4
Name: oled-studio
Version: 0.1.0
Summary: OLED Studio Python SDK — API key in, WAV audio out.
Author: OLED Studio
License-Expression: MIT
Project-URL: Homepage, https://github.com/kenmentor/oled_Studio
Project-URL: Repository, https://github.com/kenmentor/oled_Studio.git
Keywords: tts,text-to-speech,oled-studio
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31
Dynamic: license-file

# OLED Studio — Python SDK (`oled-studio`)

API key in, WAV audio out. Thin wrapper over the v1 HTTP contract in `server/` —
no new endpoints, no magic.

## Install

```bash
pip install oled-studio
# …or from this repo:
pip install -e ./libraries/python
```

Needs Python 3.9+ and `requests` (installed automatically).

## Quickstart

```python
from oled import Oled

oled = Oled(api_key="oled_sk_live_…")  # or OLED_API_KEY env
# oled = Oled(api_key="…", base_url="https://oled-studio.onrender.com")

print(oled.health())        # {ok, provider, model_version, sample_rate, voices}
print(oled.list_voices())   # [{id, label, accent, language, enabled, sample_url}]

result = oled.speak("Hello Lagos!", voice="ada", save_to="hello.wav")
print(result.voice_id, result.synth_time, result.balance_chars)

# Streaming (SSE → raw PCM16 chunks; save_to wraps them into a .wav):
for pcm in oled.speak_stream("A longer passage…", voice="ada", save_to="long.wav"):
    print(f"got {len(pcm)} bytes of PCM")
print(oled.last_stream)
```

Preview lane (free docs/demo render, zero debit):

```python
oled.speak("Test the voice.", voice="ada", preview=True, save_to="preview.wav")
```

Voices are **metadata records** on the server (`POST /v1/voices`):

```python
oled.create_voice("chioma", label="Chioma", accent="Nigerian · Igbo")
oled.disable_voice("chioma")
oled.enable_voice("chioma")
oled.delete_voice("chioma")
```

## Errors

Every server failure raises `OledError` with `.code` / `.status`:

- `unknown_voice` · `voice_disabled` · `bad_request`
- `insufficient_credits` (top up, then retry)
- `synthesis_failed` · `invalid_key` / `unauthorized`

## Voice cloning — not on the server yet

`oled.clone_from_audio(...)` **always raises** `CloneNotSupportedError`.
The v1 backend has no audio-upload / clone endpoint (voice records are
`id/label/accent/language` only); true cloning lands with the Qwen checkpoint
(`TTS_PROVIDER=qwen`). The method exists so future code fails loudly instead
of silently faking a clone.
