|
1 | 1 | # Fish Audio Python SDK |
2 | 2 |
|
3 | | -To provide convenient Python program integration for https://docs.fish.audio. |
| 3 | +[](https://badge.fury.io/py/fish-audio-sdk) |
| 4 | +[](https://pypi.org/project/fish-audio-sdk/) |
| 5 | +[](https://github.com/fishaudio/fish-audio-python/actions) |
| 6 | +[](https://codecov.io/gh/fishaudio/fish-audio-python) |
| 7 | +[](https://pypi.org/project/fish-audio-sdk/) |
| 8 | +[](https://github.com/fishaudio/fish-audio-python/blob/main/LICENSE) |
4 | 9 |
|
5 | | -## Install |
| 10 | +The official Python library for the Fish Audio API - AI-powered text-to-speech, voice cloning, and speech recognition. |
6 | 11 |
|
7 | | -```bash |
8 | | -pip install fish-audio-sdk |
9 | | -``` |
10 | | -> [!NOTE] |
11 | | -> The new release has not officially been released yet - please see legacy SDK documentation for now. |
| 12 | +[Documentation](https://docs.fish.audio) | [API Reference](https://docs.fish.audio) | [Examples](./examples/) | [Discord](https://fish.audio) |
12 | 13 |
|
13 | | -## Usage |
| 14 | +--- |
14 | 15 |
|
15 | | -### New SDK (Recommended) |
| 16 | +## Important: New API Available |
16 | 17 |
|
17 | | -The new SDK uses the `fishaudio` module: |
| 18 | +> **We've released a major update to the Fish Audio Python SDK!** |
| 19 | +> |
| 20 | +> The new API (`fishaudio` module) offers improved ergonomics, better type safety, and enhanced features. The legacy SDK (`fish_audio_sdk` module) continues to be supported for existing projects, but we recommend using the new API for all new development. |
| 21 | +> |
| 22 | +> **Migration:** Both APIs are available in the same package. You can migrate at your own pace. See our [Migration Guide](https://docs.fish.audio) for details. |
18 | 23 |
|
19 | | -```python |
20 | | -from fishaudio import FishAudio |
| 24 | +--- |
21 | 25 |
|
22 | | -client = FishAudio(api_key="your_api_key") |
| 26 | +## Quick Start |
| 27 | + |
| 28 | +### Installation |
| 29 | + |
| 30 | +```bash |
| 31 | +pip install fish-audio-sdk |
23 | 32 | ``` |
24 | 33 |
|
25 | | -You can customize the base URL: |
| 34 | +### Basic Usage |
26 | 35 |
|
27 | 36 | ```python |
28 | 37 | from fishaudio import FishAudio |
| 38 | +from fishaudio.utils import save |
29 | 39 |
|
30 | | -client = FishAudio(api_key="your_api_key", base_url="https://your-proxy-domain") |
| 40 | +# Set your API key via environment variable: export FISH_AUDIO_API_KEY="your-api-key" |
| 41 | +# Or pass it directly: FishAudio(api_key="your-api-key") |
| 42 | +client = FishAudio() |
| 43 | + |
| 44 | +# Convert text to speech |
| 45 | +audio = client.tts.convert(text="Hello from Fish Audio!") |
| 46 | +save(audio, "output.mp3") |
31 | 47 | ``` |
32 | 48 |
|
33 | | -### Legacy SDK |
| 49 | +[Get your API key](https://fish.audio) | [Full Getting Started Guide](https://docs.fish.audio) |
34 | 50 |
|
35 | | -The legacy SDK uses the `fish_audio_sdk` module. Initialize a `Session` to use APIs. All APIs have synchronous and asynchronous versions. If you want to use the asynchronous version of the API, you only need to rewrite the original `session.api_call(...)` to `session.api_call.awaitable(...)`. |
| 51 | +--- |
36 | 52 |
|
37 | | -```python |
38 | | -from fish_audio_sdk import Session |
| 53 | +## Key Features |
39 | 54 |
|
40 | | -session = Session("your_api_key") |
41 | | -``` |
| 55 | +- **Text-to-Speech** - Natural-sounding voice synthesis with multiple voice options |
| 56 | +- **Voice Cloning** - Create custom voices using reference audio samples |
| 57 | +- **Real-time Streaming** - Low-latency audio generation via WebSocket connections |
| 58 | +- **Speech-to-Text (ASR)** - Accurate automatic speech recognition with language detection |
| 59 | +- **Voice Management** - Create, update, and organize custom voice models |
| 60 | +- **Sync and Async APIs** - Full support for both synchronous and asynchronous operations |
| 61 | +- **Type Safety** - Complete type hints with Pydantic models throughout |
42 | 62 |
|
43 | | -Sometimes, you may need to change our endpoint to another address. You can use |
| 63 | +--- |
| 64 | + |
| 65 | +## Examples |
| 66 | + |
| 67 | +### Text-to-Speech |
44 | 68 |
|
45 | 69 | ```python |
46 | | -from fish_audio_sdk import Session |
| 70 | +from fishaudio import FishAudio |
| 71 | +from fishaudio.utils import save |
47 | 72 |
|
48 | | -session = Session("your_api_key", base_url="https://your-proxy-domain") |
| 73 | +client = FishAudio() |
| 74 | +audio = client.tts.convert(text="Hello, world!") |
| 75 | +save(audio, "output.mp3") |
49 | 76 | ``` |
50 | 77 |
|
51 | | -### Text to speech |
| 78 | +### Voice Cloning with Reference Audio |
52 | 79 |
|
53 | 80 | ```python |
54 | | -from fish_audio_sdk import Session, TTSRequest |
| 81 | +from fishaudio import FishAudio |
55 | 82 |
|
56 | | -session = Session("your_api_key") |
| 83 | +client = FishAudio() |
57 | 84 |
|
58 | | -with open("r.mp3", "wb") as f: |
59 | | - for chunk in session.tts(TTSRequest(text="Hello, world!")): |
60 | | - f.write(chunk) |
| 85 | +# Use a reference voice for cloning |
| 86 | +with open("reference.wav", "rb") as f: |
| 87 | + audio = client.tts.convert( |
| 88 | + text="This will sound like the reference voice!", |
| 89 | + reference_audio=f.read(), |
| 90 | + reference_text="Transcription of the reference audio" |
| 91 | + ) |
61 | 92 | ``` |
62 | 93 |
|
63 | | -Or use async version: |
| 94 | +### Real-time Streaming |
64 | 95 |
|
65 | 96 | ```python |
66 | | -import asyncio |
67 | | -import aiofiles |
68 | | - |
69 | | -from fish_audio_sdk import Session, TTSRequest |
70 | | - |
71 | | -session = Session("your_api_key") |
| 97 | +from fishaudio import FishAudio |
| 98 | +from fishaudio.utils import play |
72 | 99 |
|
| 100 | +client = FishAudio() |
73 | 101 |
|
74 | | -async def main(): |
75 | | - async with aiofiles.open("r.mp3", "wb") as f: |
76 | | - async for chunk in session.tts.awaitable( |
77 | | - TTSRequest(text="Hello, world!"), |
78 | | - ): |
79 | | - await f.write(chunk) |
80 | | - |
| 102 | +# Stream audio in real-time |
| 103 | +audio_stream = client.tts.stream( |
| 104 | + text="This audio streams as it's generated", |
| 105 | + latency="balanced" |
| 106 | +) |
81 | 107 |
|
82 | | -asyncio.run(main()) |
| 108 | +play(audio_stream) |
83 | 109 | ``` |
84 | 110 |
|
85 | | -#### Reference Audio |
| 111 | +### Speech Recognition (ASR) |
86 | 112 |
|
87 | 113 | ```python |
88 | | -from fish_audio_sdk import TTSRequest |
| 114 | +from fishaudio import FishAudio |
89 | 115 |
|
90 | | -TTSRequest( |
91 | | - text="Hello, world!", |
92 | | - reference_id="your_model_id", |
93 | | -) |
| 116 | +client = FishAudio() |
| 117 | + |
| 118 | +# Transcribe audio to text |
| 119 | +with open("audio.wav", "rb") as f: |
| 120 | + result = client.asr.transcribe(audio=f.read()) |
| 121 | + print(result.text) |
94 | 122 | ``` |
95 | 123 |
|
96 | | -Or just use `ReferenceAudio` in `TTSRequest`: |
| 124 | +### List and Filter Voices |
97 | 125 |
|
98 | 126 | ```python |
99 | | -from fish_audio_sdk import TTSRequest, ReferenceAudio |
100 | | - |
101 | | -TTSRequest( |
102 | | - text="Hello, world!", |
103 | | - references=[ |
104 | | - ReferenceAudio( |
105 | | - audio=audio_file.read(), |
106 | | - text="reference audio text", |
107 | | - ) |
108 | | - ], |
109 | | -) |
110 | | -``` |
| 127 | +from fishaudio import FishAudio |
111 | 128 |
|
112 | | -### List models |
| 129 | +client = FishAudio() |
113 | 130 |
|
114 | | -```python |
115 | | -models = session.list_models() |
116 | | -print(models) |
| 131 | +# List available voices |
| 132 | +voices = client.voices.list(language="en") |
| 133 | + |
| 134 | +for voice in voices: |
| 135 | + print(f"{voice.title} - {voice.id}") |
117 | 136 | ``` |
118 | 137 |
|
119 | | -Or use async version: |
| 138 | +### Async Usage |
120 | 139 |
|
121 | 140 | ```python |
122 | 141 | import asyncio |
123 | | - |
| 142 | +from fishaudio import AsyncFishAudio |
124 | 143 |
|
125 | 144 | async def main(): |
126 | | - models = await session.list_models.awaitable() |
127 | | - print(models) |
| 145 | + client = AsyncFishAudio() |
128 | 146 |
|
| 147 | + audio = await client.tts.convert(text="Async text-to-speech!") |
| 148 | + # Process audio... |
129 | 149 |
|
130 | 150 | asyncio.run(main()) |
131 | 151 | ``` |
132 | 152 |
|
133 | | - |
134 | | - |
135 | | -### Get a model info by id |
| 153 | +### Check Account Credits |
136 | 154 |
|
137 | 155 | ```python |
138 | | -model = session.get_model("your_model_id") |
139 | | -print(model) |
| 156 | +from fishaudio import FishAudio |
| 157 | + |
| 158 | +client = FishAudio() |
| 159 | +credits = client.account.get_credits() |
| 160 | +print(f"Remaining credits: {credits.credit}") |
140 | 161 | ``` |
141 | 162 |
|
142 | | -Or use async version: |
| 163 | +[More examples in /examples directory](./examples/) |
143 | 164 |
|
144 | | -```python |
145 | | -import asyncio |
| 165 | +--- |
146 | 166 |
|
| 167 | +## Documentation |
147 | 168 |
|
148 | | -async def main(): |
149 | | - model = await session.get_model.awaitable("your_model_id") |
150 | | - print(model) |
| 169 | +- [API Reference](https://docs.fish.audio) - Complete API documentation with all parameters and options |
| 170 | +- [Tutorials & Guides](https://docs.fish.audio) - Step-by-step tutorials for common use cases |
| 171 | +- [Examples](./examples/) - Sample code demonstrating various features |
| 172 | +- [Migration Guide](https://docs.fish.audio) - Guide for upgrading from the legacy SDK |
151 | 173 |
|
| 174 | +--- |
152 | 175 |
|
153 | | -asyncio.run(main()) |
154 | | -``` |
| 176 | +## Requirements |
155 | 177 |
|
156 | | -### Create a model |
| 178 | +- Python 3.9 or higher |
| 179 | +- Fish Audio API key - [Get one here](https://fish.audio) |
157 | 180 |
|
158 | | -```python |
159 | | -model = session.create_model( |
160 | | - title="test", |
161 | | - description="test", |
162 | | - voices=[voice_file.read(), other_voice_file.read()], |
163 | | - cover_image=image_file.read(), |
164 | | -) |
165 | | -print(model) |
166 | | -``` |
| 181 | +### Optional Dependencies |
167 | 182 |
|
168 | | -Or use async version: |
| 183 | +For audio playback utilities: |
169 | 184 |
|
170 | | -```python |
171 | | -import asyncio |
| 185 | +```bash |
| 186 | +pip install fish-audio-sdk[utils] |
| 187 | +``` |
172 | 188 |
|
| 189 | +This installs `sounddevice` and `soundfile` for the `play()` utility function. |
173 | 190 |
|
174 | | -async def main(): |
175 | | - model = await session.create_model.awaitable( |
176 | | - title="test", |
177 | | - description="test", |
178 | | - voices=[voice_file.read(), other_voice_file.read()], |
179 | | - cover_image=image_file.read(), |
180 | | - ) |
181 | | - print(model) |
| 191 | +--- |
182 | 192 |
|
| 193 | +## Community & Support |
183 | 194 |
|
184 | | -asyncio.run(main()) |
185 | | -``` |
| 195 | +- [Discord Community](https://fish.audio) - Join our community for discussions and support |
| 196 | +- [GitHub Issues](https://github.com/fishaudio/fish-audio-python/issues) - Report bugs or request features |
| 197 | +- [Documentation](https://docs.fish.audio) - Comprehensive guides and API reference |
186 | 198 |
|
| 199 | +--- |
187 | 200 |
|
188 | | -### Delete a model |
| 201 | +## License |
189 | 202 |
|
190 | | -```python |
191 | | -session.delete_model("your_model_id") |
192 | | -``` |
| 203 | +This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. |
193 | 204 |
|
194 | | -Or use async version: |
195 | | - |
196 | | -```python |
197 | | -import asyncio |
| 205 | +--- |
198 | 206 |
|
| 207 | +## Legacy SDK |
199 | 208 |
|
200 | | -async def main(): |
201 | | - await session.delete_model.awaitable("your_model_id") |
| 209 | +The legacy `fish_audio_sdk` module is still available for existing projects: |
202 | 210 |
|
| 211 | +```python |
| 212 | +from fish_audio_sdk import Session |
203 | 213 |
|
204 | | -asyncio.run(main()) |
| 214 | +session = Session("your_api_key") |
205 | 215 | ``` |
| 216 | + |
| 217 | +We recommend migrating to the new `fishaudio` module for new projects. See our [Migration Guide](https://docs.fish.audio) for assistance. |
0 commit comments