|
2 | 2 |
|
3 | 3 | import pytest |
4 | 4 |
|
| 5 | +from fishaudio import WebSocketOptions |
5 | 6 | from fishaudio.types import Prosody, TTSConfig, TextEvent, FlushEvent |
6 | 7 | from .conftest import TEST_REFERENCE_ID |
7 | 8 |
|
@@ -118,6 +119,59 @@ def text_stream(): |
118 | 119 | with pytest.raises(WebSocketError, match="WebSocket stream ended with error"): |
119 | 120 | list(client.tts.stream_websocket(text_stream())) |
120 | 121 |
|
| 122 | + def test_websocket_very_long_generation_with_timeout(self, client, save_audio): |
| 123 | + """ |
| 124 | + Test that very long text generation succeeds with increased timeout. |
| 125 | +
|
| 126 | + This test generates a very long response that could potentially take >20 seconds |
| 127 | + to fully generate, which would cause a WebSocketNetworkError with the default |
| 128 | + keepalive_ping_timeout_seconds=20. By using an increased timeout of 60 seconds, |
| 129 | + we can handle longer generation times without disconnection. |
| 130 | +
|
| 131 | + This is the SOLUTION to issue #47. To reproduce the timeout issue, run: |
| 132 | + python reproduce_issue_47.py --mode=both |
| 133 | + """ |
| 134 | + # Use significantly increased timeout to handle very long generations |
| 135 | + ws_options = WebSocketOptions( |
| 136 | + keepalive_ping_timeout_seconds=60.0, |
| 137 | + keepalive_ping_interval_seconds=30.0, |
| 138 | + ) |
| 139 | + |
| 140 | + def text_stream(): |
| 141 | + # Generate a very long piece of text that will take significant time to process |
| 142 | + long_text = [ |
| 143 | + "This is a test of very long form text-to-speech generation. ", |
| 144 | + "We are testing the ability to handle extended generation times without timing out. ", |
| 145 | + "The default WebSocket keepalive timeout of 20 seconds can be insufficient for long responses. ", |
| 146 | + "By increasing the keepalive_ping_timeout_seconds to 60 seconds, we allow for longer gaps between chunks. ", |
| 147 | + "This is particularly important for conversational AI applications where responses can be quite lengthy. ", |
| 148 | + "The WebSocket connection should remain stable throughout the entire generation process. ", |
| 149 | + "We include enough text here to ensure the generation takes a substantial amount of time. ", |
| 150 | + "This helps verify that the increased timeout setting is working correctly. ", |
| 151 | + "The audio streaming should continue smoothly without any network errors. ", |
| 152 | + "Each sentence adds more content to be synthesized into speech. ", |
| 153 | + "The system should handle this gracefully with the custom WebSocket options. ", |
| 154 | + "This demonstrates the practical value of the WebSocketOptions feature. ", |
| 155 | + "Users can now configure timeouts based on their specific use case requirements. ", |
| 156 | + "Long-form content generation is now much more reliable. ", |
| 157 | + "The implementation passes through all necessary parameters to the underlying httpx_ws library. ", |
| 158 | + ] |
| 159 | + for sentence in long_text: |
| 160 | + yield sentence |
| 161 | + |
| 162 | + # This should succeed with increased timeout |
| 163 | + audio_chunks = list( |
| 164 | + client.tts.stream_websocket(text_stream(), ws_options=ws_options) |
| 165 | + ) |
| 166 | + |
| 167 | + assert len(audio_chunks) > 0, "Should receive audio chunks for very long text" |
| 168 | + complete_audio = b"".join(audio_chunks) |
| 169 | + # Very long text should produce substantial audio |
| 170 | + assert len(complete_audio) > 10000, ( |
| 171 | + "Very long text should produce substantial audio data" |
| 172 | + ) |
| 173 | + save_audio(audio_chunks, "test_websocket_very_long_with_timeout.mp3") |
| 174 | + |
121 | 175 |
|
122 | 176 | class TestAsyncTTSWebSocketIntegration: |
123 | 177 | """Test async TTS WebSocket streaming with real API.""" |
|
0 commit comments