Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ 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
Expand Down
12 changes: 6 additions & 6 deletions src/fishaudio/resources/tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def stream(
latency: Optional[LatencyMode] = None,
speed: Optional[float] = None,
config: TTSConfig = TTSConfig(),
model: Model = "s2-pro",
model: Union[Model, str] = "s2.1-pro",
request_options: Optional[RequestOptions] = None,
) -> AudioStream:
"""
Expand Down Expand Up @@ -166,7 +166,7 @@ def convert(
latency: Optional[LatencyMode] = None,
speed: Optional[float] = None,
config: TTSConfig = TTSConfig(),
model: Model = "s2-pro",
model: Union[Model, str] = "s2.1-pro",
request_options: Optional[RequestOptions] = None,
) -> bytes:
"""
Expand Down Expand Up @@ -228,7 +228,7 @@ def stream_websocket(
latency: Optional[LatencyMode] = None,
speed: Optional[float] = None,
config: TTSConfig = TTSConfig(),
model: Model = "s2-pro",
model: Union[Model, str] = "s2.1-pro",
max_workers: int = 10,
ws_options: Optional[WebSocketOptions] = None,
) -> Iterator[bytes]:
Expand Down Expand Up @@ -386,7 +386,7 @@ async def stream(
latency: Optional[LatencyMode] = None,
speed: Optional[float] = None,
config: TTSConfig = TTSConfig(),
model: Model = "s2-pro",
model: Union[Model, str] = "s2.1-pro",
request_options: Optional[RequestOptions] = None,
) -> AsyncAudioStream:
"""
Expand Down Expand Up @@ -471,7 +471,7 @@ async def convert(
latency: Optional[LatencyMode] = None,
speed: Optional[float] = None,
config: TTSConfig = TTSConfig(),
model: Model = "s2-pro",
model: Union[Model, str] = "s2.1-pro",
request_options: Optional[RequestOptions] = None,
) -> bytes:
"""
Expand Down Expand Up @@ -534,7 +534,7 @@ async def stream_websocket(
latency: Optional[LatencyMode] = None,
speed: Optional[float] = None,
config: TTSConfig = TTSConfig(),
model: Model = "s2-pro",
model: Union[Model, str] = "s2.1-pro",
ws_options: Optional[WebSocketOptions] = None,
):
"""
Expand Down
4 changes: 2 additions & 2 deletions src/fishaudio/types/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class PaginatedResponse(BaseModel, Generic[T]):


# Model types
Model = Literal["speech-1.5", "speech-1.6", "s1", "s2-pro"]
Model = Literal["s1", "s2-pro", "s2.1-pro"]

# Deprecated models
DEPRECATED_MODELS = {"speech-1.5", "speech-1.6"}
Expand All @@ -32,7 +32,7 @@ def warn_if_deprecated_model(model: str) -> None:
"""Emit a deprecation warning if a legacy model is used."""
if model in DEPRECATED_MODELS:
warnings.warn(
f"Model '{model}' is deprecated. Use 's1' or 's2-pro' instead.",
f"Model '{model}' is deprecated. Use 's2.1-pro' instead.",
DeprecationWarning,
stacklevel=3,
)
Expand Down
7 changes: 6 additions & 1 deletion tests/unit/test_tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def test_stream_basic(self, tts_client, mock_client_wrapper):

# Check headers
assert call_args[1]["headers"]["Content-Type"] == "application/msgpack"
assert call_args[1]["headers"]["model"] == "s2-pro" # default model
assert call_args[1]["headers"]["model"] == "s2.1-pro" # default model

# Check payload was msgpack encoded
assert "content" in call_args[1]
Expand All @@ -84,6 +84,8 @@ def test_convert_basic(self, tts_client, mock_client_wrapper):

# Verify request was made correctly
mock_client_wrapper.request.assert_called_once()
call_args = mock_client_wrapper.request.call_args
assert call_args[1]["headers"]["model"] == "s2.1-pro"

def test_convert_with_reference_id(self, tts_client, mock_client_wrapper):
"""Test TTS with reference voice ID."""
Expand Down Expand Up @@ -510,6 +512,7 @@ async def async_iter_bytes():

assert call_args[0][0] == "POST"
assert call_args[0][1] == "/v1/tts"
assert call_args[1]["headers"]["model"] == "s2.1-pro"

@pytest.mark.asyncio
async def test_convert_basic(self, async_tts_client, async_mock_client_wrapper):
Expand All @@ -533,6 +536,8 @@ async def async_iter_bytes():

# Verify request was made
async_mock_client_wrapper.request.assert_called_once()
call_args = async_mock_client_wrapper.request.call_args
assert call_args[1]["headers"]["model"] == "s2.1-pro"

@pytest.mark.asyncio
async def test_convert_with_reference_id(
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_tts_realtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def test_stream_websocket_basic(
# Verify WebSocket connection was created
mock_connect_ws.assert_called_once()
assert mock_connect_ws.call_args[0][0] == "/v1/tts/live"
assert mock_connect_ws.call_args[1]["headers"]["model"] == "s2.1-pro"

@pytest.mark.filterwarnings("ignore::DeprecationWarning")
@patch("fishaudio.resources.tts.connect_ws")
Expand Down Expand Up @@ -425,6 +426,7 @@ async def text_stream():
# Verify WebSocket connection was created
mock_aconnect_ws.assert_called_once()
assert mock_aconnect_ws.call_args[0][0] == "/v1/tts/live"
assert mock_aconnect_ws.call_args[1]["headers"]["model"] == "s2.1-pro"

@pytest.mark.filterwarnings("ignore::DeprecationWarning")
@pytest.mark.asyncio
Expand Down
Loading