-
Notifications
You must be signed in to change notification settings - Fork 21
Update Python SDK API Reference #112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,9 @@ | ||||||||||||||
| <a id="fishaudio.core.omit"></a> | ||||||||||||||
|
|
||||||||||||||
| # fishaudio.core.omit | ||||||||||||||
|
|
||||||||||||||
| OMIT sentinel for distinguishing None from not-provided parameters. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.client_wrapper"></a> | ||||||||||||||
|
|
||||||||||||||
| # fishaudio.core.client\_wrapper | ||||||||||||||
|
|
@@ -14,7 +20,7 @@ | |||||||||||||
|
|
||||||||||||||
| Base wrapper with shared logic for sync/async clients. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.client_wrapper.BaseClientWrapper.get_headers"></a> | ||||||||||||||
|
|
||||||||||||||
| #### get\_headers | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -172,7 +178,7 @@ | |||||||||||||
| - `additional_headers` - Additional headers to include in the request | ||||||||||||||
| - `additional_query_params` - Additional query parameters to include | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.request_options.RequestOptions.get_timeout"></a> | ||||||||||||||
|
|
||||||||||||||
| #### get\_timeout | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -182,6 +188,54 @@ | |||||||||||||
|
|
||||||||||||||
| Convert timeout to httpx.Timeout if set. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.websocket_options"></a> | ||||||||||||||
|
|
||||||||||||||
| # fishaudio.core.websocket\_options | ||||||||||||||
|
|
||||||||||||||
| WebSocket-level options for WebSocket connections. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.websocket_options.WebSocketOptions"></a> | ||||||||||||||
|
|
||||||||||||||
| ## 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 | ||||||||||||||
|
Comment on lines
+218
to
+220
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Keep the default value under Line 219 is rendered as a separate attribute named Proposed fix-- `max_message_size_bytes` - Message size in bytes to receive from the server.
-- `Default` - 65536 bytes (64 KiB).
+- `max_message_size_bytes` - Message size in bytes to receive from the server.
+ Default: 65536 bytes (64 KiB).📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| 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. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.websocket_options.WebSocketOptions.to_httpx_ws_kwargs"></a> | ||||||||||||||
|
|
||||||||||||||
| #### to\_httpx\_ws\_kwargs | ||||||||||||||
|
|
||||||||||||||
| ```python | ||||||||||||||
| def to_httpx_ws_kwargs() -> dict[str, Any] | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Convert to kwargs dict for httpx_ws aconnect_ws/connect_ws. | ||||||||||||||
|
Check warning on line 237 in api-reference/sdk/python/core.mdx
|
||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.iterators"></a> | ||||||||||||||
|
|
||||||||||||||
| # fishaudio.core.iterators | ||||||||||||||
|
|
@@ -221,7 +275,7 @@ | |||||||||||||
| #### \_\_init\_\_ | ||||||||||||||
|
|
||||||||||||||
| ```python | ||||||||||||||
| def __init__(iterator: Iterator[bytes]) | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Initialize the audio iterator wrapper. | ||||||||||||||
|
|
@@ -235,7 +289,7 @@ | |||||||||||||
| #### \_\_iter\_\_ | ||||||||||||||
|
|
||||||||||||||
| ```python | ||||||||||||||
| def __iter__() -> Iterator[bytes] | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Allow direct iteration over audio chunks. | ||||||||||||||
|
|
@@ -300,7 +354,7 @@ | |||||||||||||
| #### \_\_init\_\_ | ||||||||||||||
|
|
||||||||||||||
| ```python | ||||||||||||||
| def __init__(async_iterator: AsyncIterator[bytes]) | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Initialize the async audio iterator wrapper. | ||||||||||||||
|
|
@@ -314,7 +368,7 @@ | |||||||||||||
| #### \_\_aiter\_\_ | ||||||||||||||
|
|
||||||||||||||
| ```python | ||||||||||||||
| def __aiter__() -> AsyncIterator[bytes] | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Allow direct async iteration over audio chunks. | ||||||||||||||
|
|
@@ -346,57 +400,3 @@ | |||||||||||||
| f.write(audio) | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.websocket_options"></a> | ||||||||||||||
|
|
||||||||||||||
| # fishaudio.core.websocket\_options | ||||||||||||||
|
|
||||||||||||||
| WebSocket-level options for WebSocket connections. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.websocket_options.WebSocketOptions"></a> | ||||||||||||||
|
|
||||||||||||||
| ## 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. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.websocket_options.WebSocketOptions.to_httpx_ws_kwargs"></a> | ||||||||||||||
|
|
||||||||||||||
| #### to\_httpx\_ws\_kwargs | ||||||||||||||
|
|
||||||||||||||
| ```python | ||||||||||||||
| def to_httpx_ws_kwargs() -> dict[str, Any] | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Convert to kwargs dict for httpx_ws aconnect_ws/connect_ws. | ||||||||||||||
|
|
||||||||||||||
| <a id="fishaudio.core.omit"></a> | ||||||||||||||
|
|
||||||||||||||
| # fishaudio.core.omit | ||||||||||||||
|
|
||||||||||||||
| OMIT sentinel for distinguishing None from not-provided parameters. | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ | |
| [](https://badge.fury.io/py/fish-audio-sdk) | ||
| [](https://pypi.org/project/fish-audio-sdk/) | ||
| [](https://pypi.org/project/fish-audio-sdk/) | ||
| [](https://codecov.io/gh/fishaudio/fish-audio-python) | ||
| [](https://github.com/fishaudio/fish-audio-python/blob/main/LICENSE) | ||
|
|
||
| The official Python library for the Fish Audio API | ||
|
|
@@ -91,13 +91,23 @@ | |
|
|
||
| ### 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 @@ | |
| 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 @@ | |
| 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 @@ | |
| **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) | ||
|
Comment on lines
188
to
+197
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== locate files =="
git ls-files | rg '(^|/)api-reference/sdk/python/(overview|resources)\.mdx$|(^|/)src/|^packages/|pyproject\.toml|README' || true
echo
echo "== overview snippet =="
sed -n '170,210p' api-reference/sdk/python/overview.mdx
echo
echo "== resources around method docs =="
sed -n '540,590p' api-reference/sdk/python/resources.mdx
echo
echo "== search stream_websocket occurrences =="
rg -n "stream_websocket|AsyncTTSClient|tts\.stream_websocket|for .* stream_websocket|await .* stream_websocket" api-reference/sdk/python . --glob '!**/.git/**' | head -200Repository: fishaudio/docs Length of output: 12956 🌐 Web query:
💡 Result: To perform real-time, token-by-token text-to-speech streaming with the Fish.audio Python SDK using Citations:
🌐 Web query:
💡 Result: The async for loop is the standard pattern in Python for consuming asynchronous streams, such as those provided by WebSocket clients [1]. When working with WebSocket APIs that support streaming (like text-to-speech or real-time data feeds), the client typically provides an asynchronous generator that yields chunks as they arrive over the network [1]. To use this pattern, you define an asynchronous loop that iterates over the response stream. This allows your application to process or forward each chunk immediately without waiting for the entire stream to complete [1]. Example Implementation: The following example demonstrates how to consume a stream from an asynchronous WebSocket client [1]: async def main: client = AsyncFishAudio # Define an async generator to provide input tokens/data async def data_source: async for item in your_async_source: yield item # Use async for to iterate over the WebSocket stream as chunks arrive async for chunk in client.tts.stream_websocket(data_source): # Process each chunk as it arrives process(chunk) asyncio.run(main) Key implementation details: - Async Generator: The method (e.g., stream_websocket) is designed as an asynchronous generator [1]. - Non-blocking: By using async for, your program remains responsive, allowing other tasks to run while waiting for new chunks to arrive from the WebSocket connection [1]. - Protocol Handling: While high-level SDKs often handle framing (such as MessagePack or JSON) automatically, direct WebSocket implementations require manual management of message framing and connection state if not using a library-provided method [1]. Citations: 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== websocket docs =="
for f in api-reference/sdk/python/overview.mdx developer-guide/sdk-guide/python/websocket.mdx; do
if [ -f "$f" ]; then
echo "-- $f --"
sed -n '1,240p' "$f"
fi
done
echo
echo "== realtime streaming docs sync/async snippets =="
sed -n '180,210p' features/realtime-streaming.mdx || true
sed -n '50,75p' developer-guide/best-practices/real-time-streaming.mdx || true
sed -n '135,155p' developer-guide/best-practices/real-time-streaming.mdx || trueRepository: fishaudio/docs Length of output: 8648 Use async iteration for
🤖 Prompt for AI Agents |
||
|
|
||
| ### Voice Cloning | ||
|
|
||
|
|
@@ -232,7 +232,7 @@ | |
| ) | ||
| ``` | ||
|
|
||
| [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 @@ | |
| from fishaudio.exceptions import ( | ||
| AuthenticationError, | ||
| RateLimitError, | ||
| NotFoundError, | ||
| APIError, | ||
| FishAudioError, | ||
| ValidationError, | ||
| FishAudioError | ||
| ) | ||
|
|
||
| try: | ||
|
|
@@ -260,12 +259,10 @@ | |
| 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 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Add required frontmatter to both API-reference pages.
Both pages begin with generated anchors. Neither page declares the required YAML
titleanddescription.api-reference/sdk/python/core.mdx#L1-L6: Add frontmatter before<a id="fishaudio.core.omit"></a>.api-reference/sdk/python/utils.mdx#L1-L5: Add frontmatter before<a id="fishaudio.utils.stream"></a>.As per coding guidelines, do not skip frontmatter on any MDX file. Include a clear title and description in the YAML frontmatter.
📍 Affects 2 files
api-reference/sdk/python/core.mdx#L1-L6(this comment)api-reference/sdk/python/utils.mdx#L1-L5🤖 Prompt for AI Agents
Source: Coding guidelines