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) - ``` -