Quickstart: lexigram-multimedia-tts
Synthesize speech from text, wired through the Lexigram DI container. The default backend hits a local HTTP reference server, so it works with zero API keys — no cloud account, no secret setup.
Install
Section titled “Install”uv add lexigram-multimedia-ttsOptional extras pull in a backend’s SDK or server runtime:
uv add "lexigram-multimedia-tts[elevenlabs]" # ElevenLabs APIuv add "lexigram-multimedia-tts[openai]" # OpenAI TTS APIuv add "lexigram-multimedia-tts[chatterbox-server]" # local Chatterbox (torch)uv add "lexigram-multimedia-tts[kokoro-server]" # local Kokoro-82Muv add "lexigram-multimedia-tts[f5-tts-server]" # local F5-TTS voice cloning (torch)uv add "lexigram-multimedia-tts[piper-server]" # local Piper (ONNX, CPU)
lexigram-multimedia-ttsdepends onlexigramandlexigram-contracts(installed automatically).aiohttpis a hard dependency used by every backend.
Minimal Working Example
Section titled “Minimal Working Example”import asyncio
from lexigram import Applicationfrom lexigram.contracts.multimedia import TTSProvider, TTSRequestfrom lexigram.di.module import Module, modulefrom lexigram.multimedia.tts import AudioTTSModule
@module(imports=[AudioTTSModule.configure()])class AppModule(Module): pass
async def main() -> None: async with Application.boot(modules=[AppModule]) as app: tts: TTSProvider = await app.container.resolve(TTSProvider) result = await tts.generate(TTSRequest(text="Hello from Lexigram", voice="alloy")) if result.is_ok(): asset = result.unwrap() # MediaAsset — raw audio bytes print(asset.mime_type, asset.has_bytes)
asyncio.run(main())Point the local-http backend at any TTS HTTP server exposing POST /generate (the simplest path is a Coqui/Piper-style server on port 5002).
What Just Happened
Section titled “What Just Happened”AudioTTSModule.configure()created aDynamicModulecarryingAudioTTSProvider, exporting theTTSProvidercontract andTTSGenerationTask.Application.boot()ran the provider lifecycle:- register —
TTSConfigis bound as a singleton; the provider builds the configured backend (LocalHttpTTSProviderby default) and binds it asTTSProvider, plus aTTSGenerationTaskwrapper. API backends additionally resolve their API key from the secrets backend by name. - boot — no extra async I/O (all wiring happened in
register()).
- register —
tts.generate(TTSRequest(...))POSTs to{backend_base_url}/generateand returns aResult[MediaAsset, TTSError]— domain failures are values, not exceptions.MediaAssetcarriesmime_type,provider,bytes_data.
Next Steps
Section titled “Next Steps”- Guide — mental model, the seven backends, common patterns
- How-Tos — task-oriented recipes
- Configuration — every config key and env-var override
- Architecture — internal design and extension points
- Troubleshooting — common failures and fixes