From f9af9e4477a3145865571342188d2ff5b3813628 Mon Sep 17 00:00:00 2001
From: fishaudio-bot <242899544+fishaudio-bot@users.noreply.github.com>
Date: Fri, 31 Jul 2026 09:41:37 +0000
Subject: [PATCH] chore: update Python SDK API reference
Auto-generated from fishaudio/fish-audio-python@448150989781e6f91c3ca9f6cc59711a87df8130
---
api-reference/sdk/python/core.mdx | 108 +-
api-reference/sdk/python/overview.mdx | 47 +-
api-reference/sdk/python/resources.mdx | 1414 ++++++++++++------------
api-reference/sdk/python/types.mdx | 156 +--
api-reference/sdk/python/utils.mdx | 100 +-
5 files changed, 911 insertions(+), 914 deletions(-)
diff --git a/api-reference/sdk/python/core.mdx b/api-reference/sdk/python/core.mdx
index 8d594f1..4864759 100644
--- a/api-reference/sdk/python/core.mdx
+++ b/api-reference/sdk/python/core.mdx
@@ -1,3 +1,9 @@
+
+
+# fishaudio.core.omit
+
+OMIT sentinel for distinguishing None from not-provided parameters.
+
# fishaudio.core.client\_wrapper
@@ -182,6 +188,54 @@ def get_timeout() -> Optional[httpx.Timeout]
Convert timeout to httpx.Timeout if set.
+
+
+# fishaudio.core.websocket\_options
+
+WebSocket-level options for WebSocket connections.
+
+
+
+## WebSocketOptions Objects
+
+```python
+class WebSocketOptions()
+```
+
+Options for configuring WebSocket connections.
+
+These options are passed directly to httpx_ws's connect_ws/aconnect_ws functions.
+For complete documentation, see https://frankie567.github.io/httpx-ws/reference/httpx_ws/
+
+**Attributes**:
+
+- `keepalive_ping_timeout_seconds` - Maximum delay the client will wait for an answer
+ to its Ping event. If the delay is exceeded, WebSocketNetworkError will be
+ raised and the connection closed. Default: 20 seconds.
+- `keepalive_ping_interval_seconds` - Interval at which the client will automatically
+ send a Ping event to keep the connection alive. Set to None to disable this
+ mechanism. Default: 20 seconds.
+- `max_message_size_bytes` - Message size in bytes to receive from the server.
+- `Default` - 65536 bytes (64 KiB).
+- `queue_size` - Size of the queue where received messages will be held until they
+ are consumed. If the queue is full, the client will stop receiving messages
+ from the server until the queue has room available. Default: 512.
+
+
+**Notes**:
+
+ Parameter descriptions adapted from httpx_ws documentation.
+
+
+
+#### to\_httpx\_ws\_kwargs
+
+```python
+def to_httpx_ws_kwargs() -> dict[str, Any]
+```
+
+Convert to kwargs dict for httpx_ws aconnect_ws/connect_ws.
+
# fishaudio.core.iterators
@@ -346,57 +400,3 @@ After calling this method, the iterator cannot be used again.
f.write(audio)
```
-
-
-# fishaudio.core.websocket\_options
-
-WebSocket-level options for WebSocket connections.
-
-
-
-## WebSocketOptions Objects
-
-```python
-class WebSocketOptions()
-```
-
-Options for configuring WebSocket connections.
-
-These options are passed directly to httpx_ws's connect_ws/aconnect_ws functions.
-For complete documentation, see https://frankie567.github.io/httpx-ws/reference/httpx_ws/
-
-**Attributes**:
-
-- `keepalive_ping_timeout_seconds` - Maximum delay the client will wait for an answer
- to its Ping event. If the delay is exceeded, WebSocketNetworkError will be
- raised and the connection closed. Default: 20 seconds.
-- `keepalive_ping_interval_seconds` - Interval at which the client will automatically
- send a Ping event to keep the connection alive. Set to None to disable this
- mechanism. Default: 20 seconds.
-- `max_message_size_bytes` - Message size in bytes to receive from the server.
-- `Default` - 65536 bytes (64 KiB).
-- `queue_size` - Size of the queue where received messages will be held until they
- are consumed. If the queue is full, the client will stop receiving messages
- from the server until the queue has room available. Default: 512.
-
-
-**Notes**:
-
- Parameter descriptions adapted from httpx_ws documentation.
-
-
-
-#### to\_httpx\_ws\_kwargs
-
-```python
-def to_httpx_ws_kwargs() -> dict[str, Any]
-```
-
-Convert to kwargs dict for httpx_ws aconnect_ws/connect_ws.
-
-
-
-# fishaudio.core.omit
-
-OMIT sentinel for distinguishing None from not-provided parameters.
-
diff --git a/api-reference/sdk/python/overview.mdx b/api-reference/sdk/python/overview.mdx
index a555021..b5ccc8d 100644
--- a/api-reference/sdk/python/overview.mdx
+++ b/api-reference/sdk/python/overview.mdx
@@ -91,13 +91,23 @@ asyncio.run(main())
### Text-to-Speech
+**Selecting a model:**
+
+```python
+# Recommended for production
+production_audio = client.tts.convert(
+ text="Production speech",
+ model="s2.1-pro",
+)
+```
+
**With custom voice:**
```python
# Use a specific voice by ID
audio = client.tts.convert(
text="Custom voice",
- reference_id="9a9cf47702da476aa4629e2506d4a857"
+ reference_id="802e3bc2b27e49c2995d23ef70e6ac89"
)
```
@@ -138,7 +148,7 @@ for chunk in client.tts.stream(text="Long content..."):
audio = client.tts.stream(text="Hello!").collect()
```
-[Learn more](https://docs.fish.audio/features/text-to-speech)
+[Learn more](https://docs.fish.audio/developer-guide/sdk-guide/python/text-to-speech)
### Speech-to-Text
@@ -154,7 +164,7 @@ for segment in result.segments:
print(f"[{segment.start:.2f}s - {segment.end:.2f}s] {segment.text}")
```
-[Learn more](https://docs.fish.audio/features/speech-to-text)
+[Learn more](https://docs.fish.audio/developer-guide/sdk-guide/python/speech-to-text)
### Real-time Streaming
@@ -175,26 +185,16 @@ play(audio_stream)
**Asynchronous:**
```python
-import asyncio
-from fishaudio import AsyncFishAudio
-
async def text_chunks():
yield "Hello, "
yield "this is "
yield "streaming!"
-async def main():
- async with AsyncFishAudio() as client:
- # stream_websocket is an async generator — iterate it, don't await the call
- audio_stream = client.tts.stream_websocket(text_chunks(), latency="balanced")
- with open("out.mp3", "wb") as f:
- async for chunk in audio_stream:
- f.write(chunk)
-
-asyncio.run(main())
+audio_stream = await client.tts.stream_websocket(text_chunks(), latency="balanced")
+play(audio_stream)
```
-[Learn more](https://docs.fish.audio/features/realtime-streaming)
+[Learn more](https://docs.fish.audio/developer-guide/sdk-guide/python/websocket)
### Voice Cloning
@@ -232,7 +232,7 @@ audio = client.tts.convert(
)
```
-[Learn more](https://docs.fish.audio/features/voice-cloning)
+[Learn more](https://docs.fish.audio/developer-guide/sdk-guide/python/voice-cloning)
## Resource Clients
@@ -249,9 +249,8 @@ audio = client.tts.convert(
from fishaudio.exceptions import (
AuthenticationError,
RateLimitError,
- NotFoundError,
- APIError,
- FishAudioError,
+ ValidationError,
+ FishAudioError
)
try:
@@ -260,12 +259,10 @@ except AuthenticationError:
print("Invalid API key")
except RateLimitError:
print("Rate limit exceeded")
-except NotFoundError:
- print("Voice model not found")
-except APIError as e:
- print(f"API error {e.status}: {e.message}") # any other HTTP error, including 422 validation
+except ValidationError as e:
+ print(f"Invalid request: {e}")
except FishAudioError as e:
- print(f"SDK error: {e}")
+ print(f"API error: {e}")
```
## Resources
diff --git a/api-reference/sdk/python/resources.mdx b/api-reference/sdk/python/resources.mdx
index be274c6..8e99e05 100644
--- a/api-reference/sdk/python/resources.mdx
+++ b/api-reference/sdk/python/resources.mdx
@@ -1,928 +1,1038 @@
-
+
-# fishaudio.resources.voices
+# fishaudio.resources.account
-Voice management namespace client.
+Account namespace client for billing and credits.
-
+
-## VoicesClient Objects
+## AccountClient Objects
```python
-class VoicesClient()
+class AccountClient()
```
-Synchronous voice management operations.
+Synchronous account operations.
-
+
-#### list
+#### get\_credits
```python
-def list(
- *,
- page_size: int = 10,
- page_number: int = 1,
- title: Optional[str] = OMIT,
- tags: Optional[Union[list[str], str]] = OMIT,
- self_only: bool = False,
- author_id: Optional[str] = OMIT,
- language: Optional[Union[list[str], str]] = OMIT,
- title_language: Optional[Union[list[str], str]] = OMIT,
- sort_by: str = "task_count",
- request_options: Optional[RequestOptions] = None
-) -> PaginatedResponse[Voice]
+def get_credits(*,
+ check_free_credit: Optional[bool] = OMIT,
+ request_options: Optional[RequestOptions] = None) -> Credits
```
-List available voices/models.
+Get API credit balance.
**Arguments**:
-- `page_size` - Number of results per page
-- `page_number` - Page number (1-indexed)
-- `title` - Filter by title
-- `tags` - Filter by tags (single tag or list)
-- `self_only` - Only return user's own voices
-- `author_id` - Filter by author ID
-- `language` - Filter by language(s)
-- `title_language` - Filter by title language(s)
-- `sort_by` - Sort field ("task_count" or "created_at")
+- `check_free_credit` - Whether to check free credit availability
- `request_options` - Request-level overrides
**Returns**:
- Paginated response with total count and voice items
+ Credits information
**Example**:
```python
client = FishAudio(api_key="...")
+ credits = client.account.get_credits()
+ print(f"Available credits: {float(credits.credit)}")
- # List all voices
- voices = client.voices.list(page_size=20)
- print(f"Total: {voices.total}")
- for voice in voices.items:
- print(f"{voice.title}: {voice.id}")
-
- # Filter by tags
- tagged = client.voices.list(tags=["male", "english"])
+ # Check free credit availability
+ credits = client.account.get_credits(check_free_credit=True)
+ if credits.has_free_credit:
+ print("Free credits available!")
```
-
+
-#### get
+#### get\_package
```python
-def get(voice_id: str,
- *,
- request_options: Optional[RequestOptions] = None) -> Voice
+def get_package(*,
+ request_options: Optional[RequestOptions] = None) -> Package
```
-Get voice by ID.
+Get package information.
**Arguments**:
-- `voice_id` - Voice model ID
- `request_options` - Request-level overrides
**Returns**:
- Voice model details
+ Package information
**Example**:
```python
client = FishAudio(api_key="...")
- voice = client.voices.get("voice_id_here")
- print(voice.title, voice.description)
+ package = client.account.get_package()
+ print(f"Balance: {package.balance}/{package.total}")
```
-
+
-#### create
+## AsyncAccountClient Objects
```python
-def create(*,
- title: str,
- voices: builtins.list[bytes],
- description: Optional[str] = OMIT,
- texts: Optional[builtins.list[str]] = OMIT,
- tags: Optional[builtins.list[str]] = OMIT,
- cover_image: Optional[bytes] = OMIT,
- visibility: Visibility = "private",
- train_mode: str = "fast",
- enhance_audio_quality: bool = True,
- request_options: Optional[RequestOptions] = None) -> Voice
+class AsyncAccountClient()
```
-Create/clone a new voice.
+Asynchronous account operations.
+
+
+
+#### get\_credits
+
+```python
+async def get_credits(
+ *,
+ check_free_credit: Optional[bool] = OMIT,
+ request_options: Optional[RequestOptions] = None) -> Credits
+```
+
+Get API credit balance (async).
**Arguments**:
-- `title` - Voice model name
-- `voices` - List of audio file bytes for training
-- `description` - Voice description
-- `texts` - Transcripts for voice samples
-- `tags` - Tags for categorization
-- `cover_image` - Cover image bytes
-- `visibility` - Visibility setting (public, unlist, private)
-- `train_mode` - Training mode (currently only "fast" supported)
-- `enhance_audio_quality` - Whether to enhance audio quality
+- `check_free_credit` - Whether to check free credit availability
- `request_options` - Request-level overrides
**Returns**:
- Created voice model
+ Credits information
**Example**:
```python
- client = FishAudio(api_key="...")
+ client = AsyncFishAudio(api_key="...")
+ credits = await client.account.get_credits()
+ print(f"Available credits: {float(credits.credit)}")
- with open("voice1.wav", "rb") as f1, open("voice2.wav", "rb") as f2:
- voice = client.voices.create(
- title="My Voice",
- voices=[f1.read(), f2.read()],
- description="Custom voice clone",
- tags=["custom", "english"]
- )
- print(f"Created: {voice.id}")
+ # Check free credit availability
+ credits = await client.account.get_credits(check_free_credit=True)
+ if credits.has_free_credit:
+ print("Free credits available!")
```
-
+
-#### update
+#### get\_package
```python
-def update(voice_id: str,
- *,
- title: Optional[str] = OMIT,
- description: Optional[str] = OMIT,
- cover_image: Optional[bytes] = OMIT,
- visibility: Optional[Visibility] = OMIT,
- tags: Optional[builtins.list[str]] = OMIT,
- request_options: Optional[RequestOptions] = None) -> None
+async def get_package(*,
+ request_options: Optional[RequestOptions] = None
+ ) -> Package
```
-Update voice metadata.
+Get package information (async).
**Arguments**:
-- `voice_id` - Voice model ID
-- `title` - New title
-- `description` - New description
-- `cover_image` - New cover image bytes
-- `visibility` - New visibility setting
-- `tags` - New tags
- `request_options` - Request-level overrides
+**Returns**:
+
+ Package information
+
+
**Example**:
```python
- client = FishAudio(api_key="...")
- client.voices.update(
- "voice_id_here",
- title="Updated Title",
- visibility="public"
- )
+ client = AsyncFishAudio(api_key="...")
+ package = await client.account.get_package()
+ print(f"Balance: {package.balance}/{package.total}")
```
-
+
-#### delete
+# fishaudio.resources.tts
+
+TTS (Text-to-Speech) namespace client.
+
+
+
+## TTSClient Objects
```python
-def delete(voice_id: str,
- *,
- request_options: Optional[RequestOptions] = None) -> None
+class TTSClient()
```
-Delete a voice.
+Synchronous TTS operations.
+
+
+
+#### stream
+
+```python
+def stream(*,
+ text: str,
+ reference_id: Optional[str] = None,
+ references: Optional[list[ReferenceAudio]] = None,
+ format: Optional[AudioFormat] = None,
+ latency: Optional[LatencyMode] = None,
+ speed: Optional[float] = None,
+ config: TTSConfig = TTSConfig(),
+ model: Union[Model, str] = "s2.1-pro",
+ request_options: Optional[RequestOptions] = None) -> AudioStream
+```
+
+Stream text-to-speech audio chunks.
**Arguments**:
-- `voice_id` - Voice model ID
+- `text` - Text to synthesize
+- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
+- `references` - Reference audio samples (overrides config.references if provided)
+- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
+- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
+- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
+- `config` - TTS configuration (audio settings, voice, model parameters)
+- `model` - TTS model to use
- `request_options` - Request-level overrides
+**Returns**:
+
+ AudioStream object that can be iterated for audio chunks
+
+
**Example**:
```python
+ from fishaudio import FishAudio
+
client = FishAudio(api_key="...")
- client.voices.delete("voice_id_here")
+
+ # Stream and process chunks
+ for chunk in client.tts.stream(text="Hello world"):
+ process_audio_chunk(chunk)
+
+ # Or collect all at once
+ audio = client.tts.stream(text="Hello world").collect()
```
-
+
-## AsyncVoicesClient Objects
+#### convert
```python
-class AsyncVoicesClient()
+def convert(*,
+ text: str,
+ reference_id: Optional[str] = None,
+ references: Optional[list[ReferenceAudio]] = None,
+ format: Optional[AudioFormat] = None,
+ latency: Optional[LatencyMode] = None,
+ speed: Optional[float] = None,
+ config: TTSConfig = TTSConfig(),
+ model: Union[Model, str] = "s2.1-pro",
+ request_options: Optional[RequestOptions] = None) -> bytes
```
-Asynchronous voice management operations.
+Convert text to speech and return complete audio as bytes.
-
+This is a convenience method that streams all audio chunks and combines them.
+For chunk-by-chunk processing, use stream() instead.
-#### list
+**Arguments**:
-```python
-async def list(
- *,
- page_size: int = 10,
- page_number: int = 1,
- title: Optional[str] = OMIT,
- tags: Optional[Union[list[str], str]] = OMIT,
- self_only: bool = False,
- author_id: Optional[str] = OMIT,
- language: Optional[Union[list[str], str]] = OMIT,
- title_language: Optional[Union[list[str], str]] = OMIT,
- sort_by: str = "task_count",
- request_options: Optional[RequestOptions] = None
-) -> PaginatedResponse[Voice]
-```
+- `text` - Text to synthesize
+- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
+- `references` - Reference audio samples (overrides config.references if provided)
+- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
+- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
+- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
+- `config` - TTS configuration (audio settings, voice, model parameters)
+- `model` - TTS model to use
+- `request_options` - Request-level overrides
+
-List available voices/models (async). See sync version for details.
+**Returns**:
-
+ Complete audio as bytes
+
-#### get
+**Example**:
-```python
-async def get(voice_id: str,
- *,
- request_options: Optional[RequestOptions] = None) -> Voice
-```
+ ```python
+ from fishaudio import FishAudio
+ from fishaudio.utils import play, save
-Get voice by ID (async). See sync version for details.
+ client = FishAudio(api_key="...")
-
+ # Get complete audio
+ audio = client.tts.convert(text="Hello world")
-#### create
+ # Play it
+ play(audio)
+
+ # Or save it
+ save(audio, "output.mp3")
+ ```
+
+
+
+#### stream\_websocket
```python
-async def create(*,
- title: str,
- voices: builtins.list[bytes],
- description: Optional[str] = OMIT,
- texts: Optional[builtins.list[str]] = OMIT,
- tags: Optional[builtins.list[str]] = OMIT,
- cover_image: Optional[bytes] = OMIT,
- visibility: Visibility = "private",
- train_mode: str = "fast",
- enhance_audio_quality: bool = True,
- request_options: Optional[RequestOptions] = None) -> Voice
+def stream_websocket(
+ text_stream: Iterable[Union[str, TextEvent, FlushEvent]],
+ *,
+ reference_id: Optional[str] = None,
+ references: Optional[list[ReferenceAudio]] = None,
+ format: Optional[AudioFormat] = None,
+ latency: Optional[LatencyMode] = None,
+ speed: Optional[float] = None,
+ config: TTSConfig = TTSConfig(),
+ model: Union[Model, str] = "s2.1-pro",
+ max_workers: int = 10,
+ ws_options: Optional[WebSocketOptions] = None) -> Iterator[bytes]
```
-Create/clone a new voice (async). See sync version for details.
+Stream text and receive audio in real-time via WebSocket.
-
+Perfect for conversational AI, live captioning, and streaming applications.
-#### update
+**Arguments**:
+
+- `text_stream` - Iterator of text chunks to stream
+- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
+- `references` - Reference audio samples (overrides config.references if provided)
+- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
+- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
+- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
+- `config` - TTS configuration (audio settings, voice, model parameters)
+- `model` - TTS model to use
+- `max_workers` - ThreadPoolExecutor workers for concurrent sender
+- `ws_options` - WebSocket connection options for configuring timeouts, message size limits, etc.
+ Useful for long-running generations that may exceed default timeout values.
+ See WebSocketOptions class for available parameters.
+
+
+**Returns**:
+
+ Iterator of audio bytes
+
+
+**Example**:
+
+ ```python
+ from fishaudio import FishAudio, TTSConfig, ReferenceAudio, WebSocketOptions
+
+ client = FishAudio(api_key="...")
+
+ def text_generator():
+ yield "Hello, "
+ yield "this is "
+ yield "streaming text!"
+
+ # Simple usage with defaults
+ with open("output.mp3", "wb") as f:
+ for audio_chunk in client.tts.stream_websocket(text_generator()):
+ f.write(audio_chunk)
+
+ # With format and speed parameters
+ with open("output.wav", "wb") as f:
+ for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ format="wav",
+ speed=1.3
+ ):
+ f.write(audio_chunk)
+
+ # With reference_id parameter
+ with open("output.mp3", "wb") as f:
+ for audio_chunk in client.tts.stream_websocket(text_generator(), reference_id="your_model_id"):
+ f.write(audio_chunk)
+
+ # With references parameter
+ with open("output.mp3", "wb") as f:
+ for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ references=[ReferenceAudio(audio=audio_bytes, text="sample")]
+ ):
+ f.write(audio_chunk)
+
+ # With WebSocket options for long-running generations
+ # Useful if you're generating very long responses that may take >20 seconds
+ ws_options = WebSocketOptions(keepalive_ping_timeout_seconds=60.0)
+ with open("output.mp3", "wb") as f:
+ for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ ws_options=ws_options
+ ):
+ f.write(audio_chunk)
+
+ # Parameters override config values
+ config = TTSConfig(format="mp3", latency="balanced")
+ with open("output.wav", "wb") as f:
+ for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ format="wav", # Parameter wins
+ config=config
+ ):
+ f.write(audio_chunk)
+ ```
+
+
+
+## AsyncTTSClient Objects
```python
-async def update(voice_id: str,
- *,
- title: Optional[str] = OMIT,
- description: Optional[str] = OMIT,
- cover_image: Optional[bytes] = OMIT,
- visibility: Optional[Visibility] = OMIT,
- tags: Optional[builtins.list[str]] = OMIT,
- request_options: Optional[RequestOptions] = None) -> None
+class AsyncTTSClient()
```
-Update voice metadata (async). See sync version for details.
+Asynchronous TTS operations.
-
+
-#### delete
+#### stream
```python
-async def delete(voice_id: str,
- *,
- request_options: Optional[RequestOptions] = None) -> None
+async def stream(
+ *,
+ text: str,
+ reference_id: Optional[str] = None,
+ references: Optional[list[ReferenceAudio]] = None,
+ format: Optional[AudioFormat] = None,
+ latency: Optional[LatencyMode] = None,
+ speed: Optional[float] = None,
+ config: TTSConfig = TTSConfig(),
+ model: Union[Model, str] = "s2.1-pro",
+ request_options: Optional[RequestOptions] = None) -> AsyncAudioStream
```
-Delete a voice (async). See sync version for details.
+Stream text-to-speech audio chunks (async).
-
+**Arguments**:
-# fishaudio.resources.account
+- `text` - Text to synthesize
+- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
+- `references` - Reference audio samples (overrides config.references if provided)
+- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
+- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
+- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
+- `config` - TTS configuration (audio settings, voice, model parameters)
+- `model` - TTS model to use
+- `request_options` - Request-level overrides
+
-Account namespace client for billing and credits.
+**Returns**:
-
+ AsyncAudioStream object that can be iterated for audio chunks
+
-## AccountClient Objects
+**Example**:
+
+ ```python
+ from fishaudio import AsyncFishAudio
+
+ client = AsyncFishAudio(api_key="...")
+
+ # Stream and process chunks
+ async for chunk in await client.tts.stream(text="Hello world"):
+ await process_audio_chunk(chunk)
+
+ # Or collect all at once
+ stream = await client.tts.stream(text="Hello world")
+ audio = await stream.collect()
+ ```
+
+
+
+#### convert
```python
-class AccountClient()
+async def convert(*,
+ text: str,
+ reference_id: Optional[str] = None,
+ references: Optional[list[ReferenceAudio]] = None,
+ format: Optional[AudioFormat] = None,
+ latency: Optional[LatencyMode] = None,
+ speed: Optional[float] = None,
+ config: TTSConfig = TTSConfig(),
+ model: Union[Model, str] = "s2.1-pro",
+ request_options: Optional[RequestOptions] = None) -> bytes
```
-Synchronous account operations.
+Convert text to speech and return complete audio as bytes (async).
-
+This is a convenience method that streams all audio chunks and combines them.
+For chunk-by-chunk processing, use stream() instead.
-#### get\_credits
+**Arguments**:
+
+- `text` - Text to synthesize
+- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
+- `references` - Reference audio samples (overrides config.references if provided)
+- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
+- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
+- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
+- `config` - TTS configuration (audio settings, voice, model parameters)
+- `model` - TTS model to use
+- `request_options` - Request-level overrides
+
+
+**Returns**:
+
+ Complete audio as bytes
+
+
+**Example**:
+
+ ```python
+ from fishaudio import AsyncFishAudio
+ from fishaudio.utils import play, save
+
+ client = AsyncFishAudio(api_key="...")
+
+ # Get complete audio
+ audio = await client.tts.convert(text="Hello world")
+
+ # Play it
+ play(audio)
+
+ # Or save it
+ save(audio, "output.mp3")
+ ```
+
+
+
+#### stream\_websocket
```python
-def get_credits(*,
- check_free_credit: Optional[bool] = OMIT,
- request_options: Optional[RequestOptions] = None) -> Credits
+async def stream_websocket(text_stream: AsyncIterable[Union[str, TextEvent,
+ FlushEvent]],
+ *,
+ reference_id: Optional[str] = None,
+ references: Optional[list[ReferenceAudio]] = None,
+ format: Optional[AudioFormat] = None,
+ latency: Optional[LatencyMode] = None,
+ speed: Optional[float] = None,
+ config: TTSConfig = TTSConfig(),
+ model: Union[Model, str] = "s2.1-pro",
+ ws_options: Optional[WebSocketOptions] = None)
```
-Get API credit balance.
+Stream text and receive audio in real-time via WebSocket (async).
+
+Perfect for conversational AI, live captioning, and streaming applications.
+
+**Arguments**:
+
+- `text_stream` - Async iterator of text chunks to stream
+- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
+- `references` - Reference audio samples (overrides config.references if provided)
+- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
+- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
+- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
+- `config` - TTS configuration (audio settings, voice, model parameters)
+- `model` - TTS model to use
+- `ws_options` - WebSocket connection options for configuring timeouts, message size limits, etc.
+ Useful for long-running generations that may exceed default timeout values.
+ See WebSocketOptions class for available parameters.
+
+
+**Returns**:
+
+ Async iterator of audio bytes
+
+
+**Example**:
+
+ ```python
+ from fishaudio import AsyncFishAudio, TTSConfig, ReferenceAudio, WebSocketOptions
+
+ client = AsyncFishAudio(api_key="...")
+
+ async def text_generator():
+ yield "Hello, "
+ yield "this is "
+ yield "async streaming!"
+
+ # Simple usage with defaults
+ async with aiofiles.open("output.mp3", "wb") as f:
+ async for audio_chunk in client.tts.stream_websocket(text_generator()):
+ await f.write(audio_chunk)
+
+ # With format and speed parameters
+ async with aiofiles.open("output.wav", "wb") as f:
+ async for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ format="wav",
+ speed=1.3
+ ):
+ await f.write(audio_chunk)
+
+ # With reference_id parameter
+ async with aiofiles.open("output.mp3", "wb") as f:
+ async for audio_chunk in client.tts.stream_websocket(text_generator(), reference_id="your_model_id"):
+ await f.write(audio_chunk)
+
+ # With references parameter
+ async with aiofiles.open("output.mp3", "wb") as f:
+ async for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ references=[ReferenceAudio(audio=audio_bytes, text="sample")]
+ ):
+ await f.write(audio_chunk)
+
+ # With WebSocket options for long-running generations
+ # Useful if you're generating very long responses that may take >20 seconds
+ ws_options = WebSocketOptions(keepalive_ping_timeout_seconds=60.0)
+ async with aiofiles.open("output.mp3", "wb") as f:
+ async for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ ws_options=ws_options
+ ):
+ await f.write(audio_chunk)
+
+ # Parameters override config values
+ config = TTSConfig(format="mp3", latency="balanced")
+ async with aiofiles.open("output.wav", "wb") as f:
+ async for audio_chunk in client.tts.stream_websocket(
+ text_generator(),
+ format="wav", # Parameter wins
+ config=config
+ ):
+ await f.write(audio_chunk)
+ ```
-**Arguments**:
+
-- `check_free_credit` - Whether to check free credit availability
-- `request_options` - Request-level overrides
-
+# fishaudio.resources.asr
-**Returns**:
+ASR (Automatic Speech Recognition) namespace client.
- Credits information
-
+
-**Example**:
+## ASRClient Objects
- ```python
- client = FishAudio(api_key="...")
- credits = client.account.get_credits()
- print(f"Available credits: {float(credits.credit)}")
+```python
+class ASRClient()
+```
- # Check free credit availability
- credits = client.account.get_credits(check_free_credit=True)
- if credits.has_free_credit:
- print("Free credits available!")
- ```
+Synchronous ASR operations.
-
+
-#### get\_package
+#### transcribe
```python
-def get_package(*,
- request_options: Optional[RequestOptions] = None) -> Package
+def transcribe(
+ *,
+ audio: bytes,
+ language: Optional[str] = OMIT,
+ include_timestamps: bool = True,
+ request_options: Optional[RequestOptions] = None) -> ASRResponse
```
-Get package information.
+Transcribe audio to text.
**Arguments**:
+- `audio` - Audio file bytes
+- `language` - Language code (e.g., "en", "zh"). Auto-detected if not provided.
+- `include_timestamps` - Whether to include timestamp information for segments
- `request_options` - Request-level overrides
**Returns**:
- Package information
+ ASRResponse with transcription text, duration, and segments
**Example**:
```python
client = FishAudio(api_key="...")
- package = client.account.get_package()
- print(f"Balance: {package.balance}/{package.total}")
+
+ with open("audio.mp3", "rb") as f:
+ audio_bytes = f.read()
+
+ result = client.asr.transcribe(audio=audio_bytes, language="en")
+ print(result.text)
+ for segment in result.segments:
+ print(f"{segment.start}-{segment.end}: {segment.text}")
```
-
+
-## AsyncAccountClient Objects
+## AsyncASRClient Objects
```python
-class AsyncAccountClient()
+class AsyncASRClient()
```
-Asynchronous account operations.
+Asynchronous ASR operations.
-
+
-#### get\_credits
+#### transcribe
```python
-async def get_credits(
+async def transcribe(
*,
- check_free_credit: Optional[bool] = OMIT,
- request_options: Optional[RequestOptions] = None) -> Credits
+ audio: bytes,
+ language: Optional[str] = OMIT,
+ include_timestamps: bool = True,
+ request_options: Optional[RequestOptions] = None) -> ASRResponse
```
-Get API credit balance (async).
+Transcribe audio to text (async).
**Arguments**:
-- `check_free_credit` - Whether to check free credit availability
+- `audio` - Audio file bytes
+- `language` - Language code (e.g., "en", "zh"). Auto-detected if not provided.
+- `include_timestamps` - Whether to include timestamp information for segments
- `request_options` - Request-level overrides
**Returns**:
- Credits information
+ ASRResponse with transcription text, duration, and segments
**Example**:
```python
client = AsyncFishAudio(api_key="...")
- credits = await client.account.get_credits()
- print(f"Available credits: {float(credits.credit)}")
-
- # Check free credit availability
- credits = await client.account.get_credits(check_free_credit=True)
- if credits.has_free_credit:
- print("Free credits available!")
- ```
-
-
-
-#### get\_package
-
-```python
-async def get_package(*,
- request_options: Optional[RequestOptions] = None
- ) -> Package
-```
-
-Get package information (async).
-
-**Arguments**:
-
-- `request_options` - Request-level overrides
-
-
-**Returns**:
-
- Package information
-
-**Example**:
+ async with aiofiles.open("audio.mp3", "rb") as f:
+ audio_bytes = await f.read()
- ```python
- client = AsyncFishAudio(api_key="...")
- package = await client.account.get_package()
- print(f"Balance: {package.balance}/{package.total}")
+ result = await client.asr.transcribe(audio=audio_bytes, language="en")
+ print(result.text)
+ for segment in result.segments:
+ print(f"{segment.start}-{segment.end}: {segment.text}")
```
-
-
-# fishaudio.resources.tts
-
-TTS (Text-to-Speech) namespace client.
-
-
-
-## TTSClient Objects
+
-```python
-class TTSClient()
-```
+# fishaudio.resources.voices
-Synchronous TTS operations.
+Voice management namespace client.
-
+
-#### stream
+## VoicesClient Objects
```python
-def stream(*,
- text: str,
- reference_id: Optional[str] = None,
- references: Optional[list[ReferenceAudio]] = None,
- format: Optional[AudioFormat] = None,
- latency: Optional[LatencyMode] = None,
- speed: Optional[float] = None,
- config: TTSConfig = TTSConfig(),
- model: Model = "s2-pro",
- request_options: Optional[RequestOptions] = None) -> AudioStream
+class VoicesClient()
```
-Stream text-to-speech audio chunks.
-
-**Arguments**:
-
-- `text` - Text to synthesize
-- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
-- `references` - Reference audio samples (overrides config.references if provided)
-- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
-- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
-- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
-- `config` - TTS configuration (audio settings, voice, model parameters)
-- `model` - TTS model to use
-- `request_options` - Request-level overrides
-
-
-**Returns**:
-
- AudioStream object that can be iterated for audio chunks
-
-
-**Example**:
-
- ```python
- from fishaudio import FishAudio
-
- client = FishAudio(api_key="...")
-
- # Stream and process chunks
- for chunk in client.tts.stream(text="Hello world"):
- process_audio_chunk(chunk)
-
- # Or collect all at once
- audio = client.tts.stream(text="Hello world").collect()
- ```
+Synchronous voice management operations.
-
+
-#### convert
+#### list
```python
-def convert(*,
- text: str,
- reference_id: Optional[str] = None,
- references: Optional[list[ReferenceAudio]] = None,
- format: Optional[AudioFormat] = None,
- latency: Optional[LatencyMode] = None,
- speed: Optional[float] = None,
- config: TTSConfig = TTSConfig(),
- model: Model = "s2-pro",
- request_options: Optional[RequestOptions] = None) -> bytes
+def list(
+ *,
+ page_size: int = 10,
+ page_number: int = 1,
+ title: Optional[str] = OMIT,
+ tags: Optional[Union[list[str], str]] = OMIT,
+ self_only: bool = False,
+ author_id: Optional[str] = OMIT,
+ language: Optional[Union[list[str], str]] = OMIT,
+ title_language: Optional[Union[list[str], str]] = OMIT,
+ sort_by: str = "task_count",
+ request_options: Optional[RequestOptions] = None
+) -> PaginatedResponse[Voice]
```
-Convert text to speech and return complete audio as bytes.
-
-This is a convenience method that streams all audio chunks and combines them.
-For chunk-by-chunk processing, use stream() instead.
+List available voices/models.
**Arguments**:
-- `text` - Text to synthesize
-- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
-- `references` - Reference audio samples (overrides config.references if provided)
-- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
-- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
-- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
-- `config` - TTS configuration (audio settings, voice, model parameters)
-- `model` - TTS model to use
+- `page_size` - Number of results per page
+- `page_number` - Page number (1-indexed)
+- `title` - Filter by title
+- `tags` - Filter by tags (single tag or list)
+- `self_only` - Only return user's own voices
+- `author_id` - Filter by author ID
+- `language` - Filter by language(s)
+- `title_language` - Filter by title language(s)
+- `sort_by` - Sort field ("task_count" or "created_at")
- `request_options` - Request-level overrides
**Returns**:
- Complete audio as bytes
+ Paginated response with total count and voice items
**Example**:
```python
- from fishaudio import FishAudio
- from fishaudio.utils import play, save
-
client = FishAudio(api_key="...")
- # Get complete audio
- audio = client.tts.convert(text="Hello world")
-
- # Play it
- play(audio)
-
- # Or save it
- save(audio, "output.mp3")
+ # List all voices
+ voices = client.voices.list(page_size=20)
+ print(f"Total: {voices.total}")
+ for voice in voices.items:
+ print(f"{voice.title}: {voice.id}")
+
+ # Filter by tags
+ tagged = client.voices.list(tags=["male", "english"])
```
-
+
-#### stream\_websocket
+#### get
```python
-def stream_websocket(
- text_stream: Iterable[Union[str, TextEvent, FlushEvent]],
+def get(voice_id: str,
*,
- reference_id: Optional[str] = None,
- references: Optional[list[ReferenceAudio]] = None,
- format: Optional[AudioFormat] = None,
- latency: Optional[LatencyMode] = None,
- speed: Optional[float] = None,
- config: TTSConfig = TTSConfig(),
- model: Model = "s2-pro",
- max_workers: int = 10,
- ws_options: Optional[WebSocketOptions] = None) -> Iterator[bytes]
+ request_options: Optional[RequestOptions] = None) -> Voice
```
-Stream text and receive audio in real-time via WebSocket.
-
-Perfect for conversational AI, live captioning, and streaming applications.
+Get voice by ID.
**Arguments**:
-- `text_stream` - Iterator of text chunks to stream
-- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
-- `references` - Reference audio samples (overrides config.references if provided)
-- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
-- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
-- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
-- `config` - TTS configuration (audio settings, voice, model parameters)
-- `model` - TTS model to use
-- `max_workers` - ThreadPoolExecutor workers for concurrent sender
-- `ws_options` - WebSocket connection options for configuring timeouts, message size limits, etc.
- Useful for long-running generations that may exceed default timeout values.
- See WebSocketOptions class for available parameters.
+- `voice_id` - Voice model ID
+- `request_options` - Request-level overrides
**Returns**:
- Iterator of audio bytes
+ Voice model details
**Example**:
```python
- from fishaudio import FishAudio, TTSConfig, ReferenceAudio, WebSocketOptions
-
client = FishAudio(api_key="...")
+ voice = client.voices.get("voice_id_here")
+ print(voice.title, voice.description)
+ ```
- def text_generator():
- yield "Hello, "
- yield "this is "
- yield "streaming text!"
+
- # Simple usage with defaults
- with open("output.mp3", "wb") as f:
- for audio_chunk in client.tts.stream_websocket(text_generator()):
- f.write(audio_chunk)
+#### create
- # With format and speed parameters
- with open("output.wav", "wb") as f:
- for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- format="wav",
- speed=1.3
- ):
- f.write(audio_chunk)
+```python
+def create(*,
+ title: str,
+ voices: builtins.list[bytes],
+ description: Optional[str] = OMIT,
+ texts: Optional[builtins.list[str]] = OMIT,
+ tags: Optional[builtins.list[str]] = OMIT,
+ cover_image: Optional[bytes] = OMIT,
+ visibility: Visibility = "private",
+ train_mode: str = "fast",
+ enhance_audio_quality: bool = True,
+ request_options: Optional[RequestOptions] = None) -> Voice
+```
- # With reference_id parameter
- with open("output.mp3", "wb") as f:
- for audio_chunk in client.tts.stream_websocket(text_generator(), reference_id="your_model_id"):
- f.write(audio_chunk)
+Create/clone a new voice.
- # With references parameter
- with open("output.mp3", "wb") as f:
- for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- references=[ReferenceAudio(audio=audio_bytes, text="sample")]
- ):
- f.write(audio_chunk)
+**Arguments**:
- # With WebSocket options for long-running generations
- # Useful if you're generating very long responses that may take >20 seconds
- ws_options = WebSocketOptions(keepalive_ping_timeout_seconds=60.0)
- with open("output.mp3", "wb") as f:
- for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- ws_options=ws_options
- ):
- f.write(audio_chunk)
+- `title` - Voice model name
+- `voices` - List of audio file bytes for training
+- `description` - Voice description
+- `texts` - Transcripts for voice samples
+- `tags` - Tags for categorization
+- `cover_image` - Cover image bytes
+- `visibility` - Visibility setting (public, unlist, private)
+- `train_mode` - Training mode (currently only "fast" supported)
+- `enhance_audio_quality` - Whether to enhance audio quality
+- `request_options` - Request-level overrides
+
- # Parameters override config values
- config = TTSConfig(format="mp3", latency="balanced")
- with open("output.wav", "wb") as f:
- for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- format="wav", # Parameter wins
- config=config
- ):
- f.write(audio_chunk)
- ```
+**Returns**:
-
+ Created voice model
+
-## AsyncTTSClient Objects
+**Example**:
-```python
-class AsyncTTSClient()
-```
+ ```python
+ client = FishAudio(api_key="...")
-Asynchronous TTS operations.
+ with open("voice1.wav", "rb") as f1, open("voice2.wav", "rb") as f2:
+ voice = client.voices.create(
+ title="My Voice",
+ voices=[f1.read(), f2.read()],
+ description="Custom voice clone",
+ tags=["custom", "english"]
+ )
+ print(f"Created: {voice.id}")
+ ```
-
+
-#### stream
+#### update
```python
-async def stream(
- *,
- text: str,
- reference_id: Optional[str] = None,
- references: Optional[list[ReferenceAudio]] = None,
- format: Optional[AudioFormat] = None,
- latency: Optional[LatencyMode] = None,
- speed: Optional[float] = None,
- config: TTSConfig = TTSConfig(),
- model: Model = "s2-pro",
- request_options: Optional[RequestOptions] = None) -> AsyncAudioStream
+def update(voice_id: str,
+ *,
+ title: Optional[str] = OMIT,
+ description: Optional[str] = OMIT,
+ cover_image: Optional[bytes] = OMIT,
+ visibility: Optional[Visibility] = OMIT,
+ tags: Optional[builtins.list[str]] = OMIT,
+ request_options: Optional[RequestOptions] = None) -> None
```
-Stream text-to-speech audio chunks (async).
+Update voice metadata.
**Arguments**:
-- `text` - Text to synthesize
-- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
-- `references` - Reference audio samples (overrides config.references if provided)
-- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
-- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
-- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
-- `config` - TTS configuration (audio settings, voice, model parameters)
-- `model` - TTS model to use
+- `voice_id` - Voice model ID
+- `title` - New title
+- `description` - New description
+- `cover_image` - New cover image bytes
+- `visibility` - New visibility setting
+- `tags` - New tags
- `request_options` - Request-level overrides
-**Returns**:
-
- AsyncAudioStream object that can be iterated for audio chunks
-
-
**Example**:
```python
- from fishaudio import AsyncFishAudio
-
- client = AsyncFishAudio(api_key="...")
-
- # Stream and process chunks
- async for chunk in await client.tts.stream(text="Hello world"):
- await process_audio_chunk(chunk)
-
- # Or collect all at once
- stream = await client.tts.stream(text="Hello world")
- audio = await stream.collect()
+ client = FishAudio(api_key="...")
+ client.voices.update(
+ "voice_id_here",
+ title="Updated Title",
+ visibility="public"
+ )
```
-
+
-#### convert
+#### delete
```python
-async def convert(*,
- text: str,
- reference_id: Optional[str] = None,
- references: Optional[list[ReferenceAudio]] = None,
- format: Optional[AudioFormat] = None,
- latency: Optional[LatencyMode] = None,
- speed: Optional[float] = None,
- config: TTSConfig = TTSConfig(),
- model: Model = "s2-pro",
- request_options: Optional[RequestOptions] = None) -> bytes
+def delete(voice_id: str,
+ *,
+ request_options: Optional[RequestOptions] = None) -> None
```
-Convert text to speech and return complete audio as bytes (async).
-
-This is a convenience method that streams all audio chunks and combines them.
-For chunk-by-chunk processing, use stream() instead.
+Delete a voice.
**Arguments**:
-- `text` - Text to synthesize
-- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
-- `references` - Reference audio samples (overrides config.references if provided)
-- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
-- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
-- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
-- `config` - TTS configuration (audio settings, voice, model parameters)
-- `model` - TTS model to use
+- `voice_id` - Voice model ID
- `request_options` - Request-level overrides
-**Returns**:
-
- Complete audio as bytes
-
-
**Example**:
```python
- from fishaudio import AsyncFishAudio
- from fishaudio.utils import play, save
+ client = FishAudio(api_key="...")
+ client.voices.delete("voice_id_here")
+ ```
- client = AsyncFishAudio(api_key="...")
+
- # Get complete audio
- audio = await client.tts.convert(text="Hello world")
+## AsyncVoicesClient Objects
- # Play it
- play(audio)
+```python
+class AsyncVoicesClient()
+```
- # Or save it
- save(audio, "output.mp3")
- ```
+Asynchronous voice management operations.
-
+
-#### stream\_websocket
+#### list
```python
-async def stream_websocket(text_stream: AsyncIterable[Union[str, TextEvent,
- FlushEvent]],
- *,
- reference_id: Optional[str] = None,
- references: Optional[list[ReferenceAudio]] = None,
- format: Optional[AudioFormat] = None,
- latency: Optional[LatencyMode] = None,
- speed: Optional[float] = None,
- config: TTSConfig = TTSConfig(),
- model: Model = "s2-pro",
- ws_options: Optional[WebSocketOptions] = None)
+async def list(
+ *,
+ page_size: int = 10,
+ page_number: int = 1,
+ title: Optional[str] = OMIT,
+ tags: Optional[Union[list[str], str]] = OMIT,
+ self_only: bool = False,
+ author_id: Optional[str] = OMIT,
+ language: Optional[Union[list[str], str]] = OMIT,
+ title_language: Optional[Union[list[str], str]] = OMIT,
+ sort_by: str = "task_count",
+ request_options: Optional[RequestOptions] = None
+) -> PaginatedResponse[Voice]
```
-Stream text and receive audio in real-time via WebSocket (async).
+List available voices/models (async). See sync version for details.
-Perfect for conversational AI, live captioning, and streaming applications.
+
-**Arguments**:
+#### get
-- `text_stream` - Async iterator of text chunks to stream
-- `reference_id` - Voice reference ID (overrides config.reference_id if provided)
-- `references` - Reference audio samples (overrides config.references if provided)
-- `format` - Audio format - "mp3", "wav", "pcm", or "opus" (overrides config.format if provided)
-- `latency` - Latency mode - "normal" or "balanced" (overrides config.latency if provided)
-- `speed` - Speech speed multiplier, e.g. 1.5 for 1.5x speed (overrides config.prosody.speed if provided)
-- `config` - TTS configuration (audio settings, voice, model parameters)
-- `model` - TTS model to use
-- `ws_options` - WebSocket connection options for configuring timeouts, message size limits, etc.
- Useful for long-running generations that may exceed default timeout values.
- See WebSocketOptions class for available parameters.
-
+```python
+async def get(voice_id: str,
+ *,
+ request_options: Optional[RequestOptions] = None) -> Voice
+```
-**Returns**:
+Get voice by ID (async). See sync version for details.
- Async iterator of audio bytes
-
+
-**Example**:
+#### create
- ```python
- from fishaudio import AsyncFishAudio, TTSConfig, ReferenceAudio, WebSocketOptions
+```python
+async def create(*,
+ title: str,
+ voices: builtins.list[bytes],
+ description: Optional[str] = OMIT,
+ texts: Optional[builtins.list[str]] = OMIT,
+ tags: Optional[builtins.list[str]] = OMIT,
+ cover_image: Optional[bytes] = OMIT,
+ visibility: Visibility = "private",
+ train_mode: str = "fast",
+ enhance_audio_quality: bool = True,
+ request_options: Optional[RequestOptions] = None) -> Voice
+```
- client = AsyncFishAudio(api_key="...")
+Create/clone a new voice (async). See sync version for details.
- async def text_generator():
- yield "Hello, "
- yield "this is "
- yield "async streaming!"
+
- # Simple usage with defaults
- async with aiofiles.open("output.mp3", "wb") as f:
- async for audio_chunk in client.tts.stream_websocket(text_generator()):
- await f.write(audio_chunk)
+#### update
- # With format and speed parameters
- async with aiofiles.open("output.wav", "wb") as f:
- async for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- format="wav",
- speed=1.3
- ):
- await f.write(audio_chunk)
+```python
+async def update(voice_id: str,
+ *,
+ title: Optional[str] = OMIT,
+ description: Optional[str] = OMIT,
+ cover_image: Optional[bytes] = OMIT,
+ visibility: Optional[Visibility] = OMIT,
+ tags: Optional[builtins.list[str]] = OMIT,
+ request_options: Optional[RequestOptions] = None) -> None
+```
- # With reference_id parameter
- async with aiofiles.open("output.mp3", "wb") as f:
- async for audio_chunk in client.tts.stream_websocket(text_generator(), reference_id="your_model_id"):
- await f.write(audio_chunk)
+Update voice metadata (async). See sync version for details.
- # With references parameter
- async with aiofiles.open("output.mp3", "wb") as f:
- async for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- references=[ReferenceAudio(audio=audio_bytes, text="sample")]
- ):
- await f.write(audio_chunk)
+
- # With WebSocket options for long-running generations
- # Useful if you're generating very long responses that may take >20 seconds
- ws_options = WebSocketOptions(keepalive_ping_timeout_seconds=60.0)
- async with aiofiles.open("output.mp3", "wb") as f:
- async for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- ws_options=ws_options
- ):
- await f.write(audio_chunk)
+#### delete
- # Parameters override config values
- config = TTSConfig(format="mp3", latency="balanced")
- async with aiofiles.open("output.wav", "wb") as f:
- async for audio_chunk in client.tts.stream_websocket(
- text_generator(),
- format="wav", # Parameter wins
- config=config
- ):
- await f.write(audio_chunk)
- ```
+```python
+async def delete(voice_id: str,
+ *,
+ request_options: Optional[RequestOptions] = None) -> None
+```
+
+Delete a voice (async). See sync version for details.
@@ -984,113 +1094,3 @@ Unknown events are ignored and iteration continues.
- `WebSocketError` - On disconnect or error finish event
-
-
-# fishaudio.resources.asr
-
-ASR (Automatic Speech Recognition) namespace client.
-
-
-
-## ASRClient Objects
-
-```python
-class ASRClient()
-```
-
-Synchronous ASR operations.
-
-
-
-#### transcribe
-
-```python
-def transcribe(
- *,
- audio: bytes,
- language: Optional[str] = OMIT,
- include_timestamps: bool = True,
- request_options: Optional[RequestOptions] = None) -> ASRResponse
-```
-
-Transcribe audio to text.
-
-**Arguments**:
-
-- `audio` - Audio file bytes
-- `language` - Language code (e.g., "en", "zh"). Auto-detected if not provided.
-- `include_timestamps` - Whether to include timestamp information for segments
-- `request_options` - Request-level overrides
-
-
-**Returns**:
-
- ASRResponse with transcription text, duration, and segments
-
-
-**Example**:
-
- ```python
- client = FishAudio(api_key="...")
-
- with open("audio.mp3", "rb") as f:
- audio_bytes = f.read()
-
- result = client.asr.transcribe(audio=audio_bytes, language="en")
- print(result.text)
- for segment in result.segments:
- print(f"{segment.start}-{segment.end}: {segment.text}")
- ```
-
-
-
-## AsyncASRClient Objects
-
-```python
-class AsyncASRClient()
-```
-
-Asynchronous ASR operations.
-
-
-
-#### transcribe
-
-```python
-async def transcribe(
- *,
- audio: bytes,
- language: Optional[str] = OMIT,
- include_timestamps: bool = True,
- request_options: Optional[RequestOptions] = None) -> ASRResponse
-```
-
-Transcribe audio to text (async).
-
-**Arguments**:
-
-- `audio` - Audio file bytes
-- `language` - Language code (e.g., "en", "zh"). Auto-detected if not provided.
-- `include_timestamps` - Whether to include timestamp information for segments
-- `request_options` - Request-level overrides
-
-
-**Returns**:
-
- ASRResponse with transcription text, duration, and segments
-
-
-**Example**:
-
- ```python
- client = AsyncFishAudio(api_key="...")
-
- async with aiofiles.open("audio.mp3", "rb") as f:
- audio_bytes = await f.read()
-
- result = await client.asr.transcribe(audio=audio_bytes, language="en")
- print(result.text)
- for segment in result.segments:
- print(f"{segment.start}-{segment.end}: {segment.text}")
- ```
-
diff --git a/api-reference/sdk/python/types.mdx b/api-reference/sdk/python/types.mdx
index 3873865..f6e5434 100644
--- a/api-reference/sdk/python/types.mdx
+++ b/api-reference/sdk/python/types.mdx
@@ -1,78 +1,3 @@
-
-
-# fishaudio.types.voices
-
-Voice and model management types.
-
-
-
-## Sample Objects
-
-```python
-class Sample(BaseModel)
-```
-
-A sample audio for a voice model.
-
-**Attributes**:
-
-- `title` - Title/name of the audio sample
-- `text` - Transcription of the spoken content in the sample
-- `task_id` - Unique identifier for the sample task
-- `audio` - URL or path to the audio file
-
-
-
-## Author Objects
-
-```python
-class Author(BaseModel)
-```
-
-Voice model author information.
-
-**Attributes**:
-
-- `id` - Unique author identifier
-- `nickname` - Author's display name
-- `avatar` - URL to author's avatar image
-
-
-
-## Voice Objects
-
-```python
-class Voice(BaseModel)
-```
-
-A voice model.
-
-Represents a TTS voice that can be used for synthesis.
-
-**Attributes**:
-
-- `id` - Unique voice model identifier (use as reference_id in TTS)
-- `type` - Model type. Options: "svc" (singing voice conversion), "tts" (text-to-speech)
-- `title` - Voice model title/name
-- `description` - Detailed description of the voice model
-- `cover_image` - URL to the voice model's cover image
-- `train_mode` - Training mode used. Options: "fast"
-- `state` - Current model state: "created", "training", "trained", or "failed"
-- `tags` - List of tags for categorization (e.g., ["male", "english", "young"])
-- `samples` - List of audio samples demonstrating the voice
-- `created_at` - Timestamp when the model was created
-- `updated_at` - Timestamp when the model was last updated
-- `languages` - List of supported language codes (e.g., ["en", "zh"])
-- `visibility` - Model visibility. Options: "public", "private", "unlist"
-- `lock_visibility` - Whether visibility setting is locked
-- `like_count` - Number of likes the model has received
-- `mark_count` - Number of bookmarks/favorites
-- `shared_count` - Number of times the model has been shared
-- `task_count` - Number of times the model has been used for generation
-- `liked` - Whether the current user has liked this model. Default: False
-- `marked` - Whether the current user has bookmarked this model. Default: False
-- `author` - Information about the voice model's creator
-
# fishaudio.types.account
@@ -205,7 +130,7 @@ All parameters have sensible defaults.
- `chunk_length` - Characters per generation chunk. Range: 100-300. Default: 200.
Lower values = faster initial response, higher values = better quality
- `latency` - Generation mode. Options: "normal" (higher quality), "balanced" (faster). Default: "balanced"
-- `reference_id` - Voice model ID from fish.audio (e.g., "9a9cf47702da476aa4629e2506d4a857").
+- `reference_id` - Voice model ID from fish.audio (e.g., "802e3bc2b27e49c2995d23ef70e6ac89").
Find IDs in voice URLs or via voices.list()
- `references` - List of reference audio samples for instant voice cloning. Default: []
- `prosody` - Speech speed and volume settings. Default: None (uses natural prosody)
@@ -378,12 +303,87 @@ Response from speech-to-text transcription.
**Attributes**:
- `text` - Complete transcription of the entire audio
-- `duration` - Total audio duration in seconds
+- `duration` - Total audio duration in milliseconds
- `segments` - List of timestamped text segments. Empty if include_timestamps=False
#### duration
-Duration in seconds
+Duration in milliseconds
+
+
+
+# fishaudio.types.voices
+
+Voice and model management types.
+
+
+
+## Sample Objects
+
+```python
+class Sample(BaseModel)
+```
+
+A sample audio for a voice model.
+
+**Attributes**:
+
+- `title` - Title/name of the audio sample
+- `text` - Transcription of the spoken content in the sample
+- `task_id` - Unique identifier for the sample task
+- `audio` - URL or path to the audio file
+
+
+
+## Author Objects
+
+```python
+class Author(BaseModel)
+```
+
+Voice model author information.
+
+**Attributes**:
+
+- `id` - Unique author identifier
+- `nickname` - Author's display name
+- `avatar` - URL to author's avatar image
+
+
+
+## Voice Objects
+
+```python
+class Voice(BaseModel)
+```
+
+A voice model.
+
+Represents a TTS voice that can be used for synthesis.
+
+**Attributes**:
+
+- `id` - Unique voice model identifier (use as reference_id in TTS)
+- `type` - Model type. Options: "svc" (singing voice conversion), "tts" (text-to-speech)
+- `title` - Voice model title/name
+- `description` - Detailed description of the voice model
+- `cover_image` - URL to the voice model's cover image
+- `train_mode` - Training mode used. Options: "fast"
+- `state` - Current model state (e.g., "ready", "training", "failed")
+- `tags` - List of tags for categorization (e.g., ["male", "english", "young"])
+- `samples` - List of audio samples demonstrating the voice
+- `created_at` - Timestamp when the model was created
+- `updated_at` - Timestamp when the model was last updated
+- `languages` - List of supported language codes (e.g., ["en", "zh"])
+- `visibility` - Model visibility. Options: "public", "private", "unlist"
+- `lock_visibility` - Whether visibility setting is locked
+- `like_count` - Number of likes the model has received
+- `mark_count` - Number of bookmarks/favorites
+- `shared_count` - Number of times the model has been shared
+- `task_count` - Number of times the model has been used for generation
+- `liked` - Whether the current user has liked this model. Default: False
+- `marked` - Whether the current user has bookmarked this model. Default: False
+- `author` - Information about the voice model's creator
diff --git a/api-reference/sdk/python/utils.mdx b/api-reference/sdk/python/utils.mdx
index 30f93ea..e76fbb6 100644
--- a/api-reference/sdk/python/utils.mdx
+++ b/api-reference/sdk/python/utils.mdx
@@ -1,3 +1,53 @@
+
+
+# fishaudio.utils.stream
+
+Audio streaming utility.
+
+
+
+#### stream
+
+```python
+def stream(audio_stream: Iterator[bytes]) -> bytes
+```
+
+Stream audio in real-time while playing it with mpv.
+
+This function plays the audio as it's being generated and
+simultaneously captures it to return the complete audio buffer.
+
+**Arguments**:
+
+- `audio_stream` - Iterator of audio byte chunks
+
+
+**Returns**:
+
+ Complete audio bytes after streaming finishes
+
+
+**Raises**:
+
+- `DependencyError` - If mpv is not installed
+
+
+**Examples**:
+
+ ```python
+ from fishaudio import FishAudio, stream
+
+ client = FishAudio(api_key="...")
+ audio_stream = client.tts.convert(text="Hello world")
+
+ # Stream and play in real-time, get complete audio
+ complete_audio = stream(audio_stream)
+
+ # Save the captured audio
+ with open("output.mp3", "wb") as f:
+ f.write(complete_audio)
+ ```
+
# fishaudio.utils.play
@@ -85,53 +135,3 @@ Save audio to a file.
save(audio_stream, "another.mp3")
```
-
-
-# fishaudio.utils.stream
-
-Audio streaming utility.
-
-
-
-#### stream
-
-```python
-def stream(audio_stream: Iterator[bytes]) -> bytes
-```
-
-Stream audio in real-time while playing it with mpv.
-
-This function plays the audio as it's being generated and
-simultaneously captures it to return the complete audio buffer.
-
-**Arguments**:
-
-- `audio_stream` - Iterator of audio byte chunks
-
-
-**Returns**:
-
- Complete audio bytes after streaming finishes
-
-
-**Raises**:
-
-- `DependencyError` - If mpv is not installed
-
-
-**Examples**:
-
- ```python
- from fishaudio import FishAudio, stream
-
- client = FishAudio(api_key="...")
- audio_stream = client.tts.convert(text="Hello world")
-
- # Stream and play in real-time, get complete audio
- complete_audio = stream(audio_stream)
-
- # Save the captured audio
- with open("output.mp3", "wb") as f:
- f.write(complete_audio)
- ```
-