-
Notifications
You must be signed in to change notification settings - Fork 111
Description
Summary
when DG returns 429 error message, it fails to parse and completely fails the request
What happened?
it should just call on_warning call back, but it's entirely failing the connection.
Steps to reproduce
n/a
Minimal code sample
n/aLogs / traceback
I think there is a gap in how DSK handles warning message between the old and new SDK version.
message:
{'type': 'Warning', 'warn_code': 'EXCESSIVE_FLUSH', 'warn_msg': 'Rate limit exceeded for flushes. Please try again later.'}
stack trace from the new SDK:
Traceback (most recent call last):
File "/app/call_handling/consumers/synthesizer/provider/deepgram.py", line 140, in _listen
await connection.start_listening()
File "/app/.venv/lib/python3.11/site-packages/deepgram/speak/v1/socket_client.py", line 84, in start_listening
parsed, is_binary = self._process_message(raw_message)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/deepgram/s\peak/v1/socket_client.py", line 62, in _process_message
processed = self._handle_json_message(raw_message)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/deepgram/speak/v1/socket_client.py", line 54, in _handle_json_message
return parse_obj_as(V1SocketClientResponse, json_data) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/deepgram/core/pydantic_utilities.py", line 43, in parse_obj_as
return adapter.validate_python(dealiased_object)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/pydantic/type_adapter.py", line 421, in validate_python
return self.validator.validate_python(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 10 validation errors for union[bytes,SpeakV1MetadataEvent,SpeakV1ControlEvent,SpeakV1WarningEvent]
bytes
Input should be a valid bytes [type=bytes_type, input_value={'type': 'Warning', 'warn...lease try again later.'}, input_type=dict]
async def start_listening(self):
...
try:
async for raw_message in self._websocket:
parsed, is_binary = self._process_message(raw_message)
...
def _handle_json_message(self, message: str) -> typing.Any:
"""Handle a JSON message by parsing it."""
json_data = json.loads(message)
return parse_obj_as(V1SocketClientResponse, json_data) # type: ignore
In the new SDK, it just tries to parse it into V1SocketClientResponse (SpeakV1WarningEvent specifically), but there is mismatch between property names, and it fails:
class SpeakV1WarningEvent(UniversalBaseModel):
"""
Warning event from the TTS WebSocket
"""
type: typing.Literal["Warning"]
"""Message type identifier"""
description: str
"""A description of what went wrong"""
code: str
"""Error code identifying the type of error"""
SpeakV1WarningEvent.description
Field required [type=missing, input_value={'type': 'Warning', 'warn...lease try again later.'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
SpeakV1WarningEvent.code
Field required [type=missing, input_value={'type': 'Warning', 'warn...lease try again later.'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
But in the previous SDK, it just handled this warning message correctly/gracefully.
previous SDK:
async def _process_text(self, message: Union[str, bytes]) -> None:
...
data = json.loads(message)
response_type = data.get("type")
...
match response_type:
...
case SpeakWebSocketEvents.Warning:
war_warning: WarningResponse = WarningResponse.from_json(message)
self._logger.verbose("WarningResponse: %s", war_warning)
await self._emit(
SpeakWebSocketEvents(SpeakWebSocketEvents.Warning),
warning=war_warning,
**dict(cast(Dict[Any, Any], self._kwargs)),
)
...
@dataclass
class WarningResponse(BaseResponse):
"""
Warning Message from the Deepgram Platform
"""
warn_code: str = ""
warn_msg: str = ""
type: str = ""
In addition to this property name discrepancy, I see previous SDK uses cls.from_dict, which I think won't hard fail even property names mismatch, while the new SDK uses pydantic, which I think is more strict about this.
Transport
HTTP
API endpoint / path
speak.v1.connect
Model(s) used
aura-2
How often?
Always
Is this a regression?
- Yes, it worked in an earlier version
Last working SDK version (if known)
4.8.1
SDK version
5.1.0
Python version
3.11
Install method
None
OS
Linux (x86_64)
Environment details
Link to minimal repro (optional)
No response
Session ID (optional)
No response
Project ID (optional)
No response
Request ID (optional)
No response
Code of Conduct
- I agree to follow this project’s Code of Conduct