From 200d19f3d67e1aac262c3b68fa9b9e6edb92f4bf Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 29 Apr 2026 13:50:51 +0100 Subject: [PATCH 1/6] chore: SDK regeneration 2026-04-29 From 5bb2f94da05cc4021a5b7e805e1f5617cabd5ae9 Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 29 Apr 2026 13:51:23 +0100 Subject: [PATCH 2/6] chore: unfreeze files pending regen --- .fernignore | 8 +- src/deepgram/agent/v1/socket_client.py.bak | 361 ++++++++++++++++++++ src/deepgram/listen/v1/socket_client.py.bak | 234 +++++++++++++ src/deepgram/listen/v2/socket_client.py.bak | 220 ++++++++++++ src/deepgram/speak/v1/socket_client.py.bak | 235 +++++++++++++ 5 files changed, 1054 insertions(+), 4 deletions(-) create mode 100644 src/deepgram/agent/v1/socket_client.py.bak create mode 100644 src/deepgram/listen/v1/socket_client.py.bak create mode 100644 src/deepgram/listen/v2/socket_client.py.bak create mode 100644 src/deepgram/speak/v1/socket_client.py.bak diff --git a/.fernignore b/.fernignore index 642889b3..5cdd1ea6 100644 --- a/.fernignore +++ b/.fernignore @@ -12,10 +12,10 @@ src/deepgram/client.py # - listen/v2 send_configure: typing.Any / raw _send shim (generator's ListenV2Configure model # and ListenV2ConfigureSuccess not used) # [temporarily frozen — manual patches listed above] -src/deepgram/agent/v1/socket_client.py -src/deepgram/listen/v1/socket_client.py -src/deepgram/listen/v2/socket_client.py -src/deepgram/speak/v1/socket_client.py +src/deepgram/agent/v1/socket_client.py.bak +src/deepgram/listen/v1/socket_client.py.bak +src/deepgram/listen/v2/socket_client.py.bak +src/deepgram/speak/v1/socket_client.py.bak # Hand-written custom tests tests/custom/test_agent_history.py diff --git a/src/deepgram/agent/v1/socket_client.py.bak b/src/deepgram/agent/v1/socket_client.py.bak new file mode 100644 index 00000000..17c3d0d2 --- /dev/null +++ b/src/deepgram/agent/v1/socket_client.py.bak @@ -0,0 +1,361 @@ +# This file was auto-generated by Fern from our API Definition. + +import json +import logging +import typing + +import websockets.sync.connection as websockets_sync_connection +from ...core.events import EventEmitterMixin, EventType +from ...core.unchecked_base_model import construct_type +from .types.agent_v1agent_audio_done import AgentV1AgentAudioDone +from .types.agent_v1agent_started_speaking import AgentV1AgentStartedSpeaking +from .types.agent_v1agent_thinking import AgentV1AgentThinking +from .types.agent_v1conversation_text import AgentV1ConversationText +from .types.agent_v1error import AgentV1Error +from .types.agent_v1function_call_request import AgentV1FunctionCallRequest +from .types.agent_v1history import AgentV1History +from .types.agent_v1inject_agent_message import AgentV1InjectAgentMessage +from .types.agent_v1inject_user_message import AgentV1InjectUserMessage +from .types.agent_v1injection_refused import AgentV1InjectionRefused +from .types.agent_v1keep_alive import AgentV1KeepAlive +from .types.agent_v1prompt_updated import AgentV1PromptUpdated +from .types.agent_v1receive_function_call_response import AgentV1ReceiveFunctionCallResponse +from .types.agent_v1send_function_call_response import AgentV1SendFunctionCallResponse +from .types.agent_v1settings import AgentV1Settings +from .types.agent_v1settings_applied import AgentV1SettingsApplied +from .types.agent_v1speak_updated import AgentV1SpeakUpdated +from .types.agent_v1think_updated import AgentV1ThinkUpdated +from .types.agent_v1update_prompt import AgentV1UpdatePrompt +from .types.agent_v1update_speak import AgentV1UpdateSpeak +from .types.agent_v1update_think import AgentV1UpdateThink +from .types.agent_v1user_started_speaking import AgentV1UserStartedSpeaking +from .types.agent_v1warning import AgentV1Warning +from .types.agent_v1welcome import AgentV1Welcome + +try: + from websockets.legacy.client import WebSocketClientProtocol # type: ignore +except ImportError: + from websockets import WebSocketClientProtocol # type: ignore + +_logger = logging.getLogger(__name__) + + +def _sanitize_numeric_types(obj: typing.Any) -> typing.Any: + """ + Recursively convert float values that are whole numbers to int. + + Workaround for Fern-generated models that type integer API fields + (like sample_rate) as float, causing JSON serialization to produce + values like 44100.0 instead of 44100. The Deepgram API rejects + float representations of integer fields. + + See: https://github.com/deepgram/internal-api-specs/issues/205 + """ + if isinstance(obj, dict): + return {k: _sanitize_numeric_types(v) for k, v in obj.items()} + elif isinstance(obj, list): + return [_sanitize_numeric_types(item) for item in obj] + elif isinstance(obj, float) and obj.is_integer(): + return int(obj) + return obj + + +V1SocketClientResponse = typing.Union[ + AgentV1ReceiveFunctionCallResponse, + AgentV1PromptUpdated, + AgentV1SpeakUpdated, + AgentV1ThinkUpdated, + AgentV1InjectionRefused, + AgentV1Welcome, + AgentV1SettingsApplied, + AgentV1ConversationText, + AgentV1UserStartedSpeaking, + AgentV1AgentThinking, + AgentV1FunctionCallRequest, + AgentV1AgentStartedSpeaking, + AgentV1AgentAudioDone, + AgentV1Error, + AgentV1Warning, + AgentV1History, + bytes, +] + + +class AsyncV1SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: WebSocketClientProtocol): + super().__init__() + self._websocket = websocket + + async def __aiter__(self): + async for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + async def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + await self._emit_async(EventType.OPEN, None) + try: + async for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + await self._emit_async(EventType.MESSAGE, parsed) + except Exception as exc: + await self._emit_async(EventType.ERROR, exc) + finally: + await self._emit_async(EventType.CLOSE, None) + + async def send_settings(self, message: AgentV1Settings) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1Settings. + """ + await self._send_model(message) + + async def send_update_speak(self, message: AgentV1UpdateSpeak) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1UpdateSpeak. + """ + await self._send_model(message) + + async def send_inject_user_message(self, message: AgentV1InjectUserMessage) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1InjectUserMessage. + """ + await self._send_model(message) + + async def send_inject_agent_message(self, message: AgentV1InjectAgentMessage) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1InjectAgentMessage. + """ + await self._send_model(message) + + async def send_function_call_response(self, message: AgentV1SendFunctionCallResponse) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1SendFunctionCallResponse. + """ + await self._send_model(message) + + async def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1KeepAlive. + """ + await self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) + + async def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1UpdatePrompt. + """ + await self._send_model(message) + + async def send_update_think(self, message: AgentV1UpdateThink) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1UpdateThink. + """ + await self._send_model(message) + + async def send_media(self, message: bytes) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a bytes. + """ + await self._send(message) + + async def recv(self) -> V1SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = await self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + async def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + await self._websocket.send(data) + + async def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + await self._send(_sanitize_numeric_types(data.dict())) + + +class V1SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: websockets_sync_connection.Connection): + super().__init__() + self._websocket = websocket + + def __iter__(self): + for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + self._emit(EventType.OPEN, None) + try: + for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + self._emit(EventType.MESSAGE, parsed) + except Exception as exc: + self._emit(EventType.ERROR, exc) + finally: + self._emit(EventType.CLOSE, None) + + def send_settings(self, message: AgentV1Settings) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1Settings. + """ + self._send_model(message) + + def send_update_speak(self, message: AgentV1UpdateSpeak) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1UpdateSpeak. + """ + self._send_model(message) + + def send_inject_user_message(self, message: AgentV1InjectUserMessage) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1InjectUserMessage. + """ + self._send_model(message) + + def send_inject_agent_message(self, message: AgentV1InjectAgentMessage) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1InjectAgentMessage. + """ + self._send_model(message) + + def send_function_call_response(self, message: AgentV1SendFunctionCallResponse) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1SendFunctionCallResponse. + """ + self._send_model(message) + + def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1KeepAlive. + """ + self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) + + def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1UpdatePrompt. + """ + self._send_model(message) + + def send_update_think(self, message: AgentV1UpdateThink) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a AgentV1UpdateThink. + """ + self._send_model(message) + + def send_media(self, message: bytes) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a bytes. + """ + self._send(message) + + def recv(self) -> V1SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + self._websocket.send(data) + + def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + self._send(_sanitize_numeric_types(data.dict())) diff --git a/src/deepgram/listen/v1/socket_client.py.bak b/src/deepgram/listen/v1/socket_client.py.bak new file mode 100644 index 00000000..5954d116 --- /dev/null +++ b/src/deepgram/listen/v1/socket_client.py.bak @@ -0,0 +1,234 @@ +# This file was auto-generated by Fern from our API Definition. + +import json +import logging +import typing + +import websockets.sync.connection as websockets_sync_connection +from ...core.events import EventEmitterMixin, EventType +from ...core.unchecked_base_model import construct_type +from .types.listen_v1close_stream import ListenV1CloseStream +from .types.listen_v1finalize import ListenV1Finalize +from .types.listen_v1keep_alive import ListenV1KeepAlive +from .types.listen_v1metadata import ListenV1Metadata +from .types.listen_v1results import ListenV1Results +from .types.listen_v1speech_started import ListenV1SpeechStarted +from .types.listen_v1utterance_end import ListenV1UtteranceEnd + +try: + from websockets.legacy.client import WebSocketClientProtocol # type: ignore +except ImportError: + from websockets import WebSocketClientProtocol # type: ignore + +_logger = logging.getLogger(__name__) +V1SocketClientResponse = typing.Union[ListenV1Results, ListenV1Metadata, ListenV1UtteranceEnd, ListenV1SpeechStarted] + + +class AsyncV1SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: WebSocketClientProtocol): + super().__init__() + self._websocket = websocket + + async def __aiter__(self): + async for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + async def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + await self._emit_async(EventType.OPEN, None) + try: + async for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + await self._emit_async(EventType.MESSAGE, parsed) + except Exception as exc: + await self._emit_async(EventType.ERROR, exc) + finally: + await self._emit_async(EventType.CLOSE, None) + + async def send_media(self, message: bytes) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a bytes. + """ + await self._send(message) + + async def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV1Finalize. + """ + await self._send_model(message or ListenV1Finalize(type="Finalize")) + + async def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV1CloseStream. + """ + await self._send_model(message or ListenV1CloseStream(type="CloseStream")) + + async def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV1KeepAlive. + """ + await self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) + + async def recv(self) -> V1SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = await self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + async def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + await self._websocket.send(data) + + async def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + await self._send(data.dict()) + + +class V1SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: websockets_sync_connection.Connection): + super().__init__() + self._websocket = websocket + + def __iter__(self): + for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + self._emit(EventType.OPEN, None) + try: + for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + self._emit(EventType.MESSAGE, parsed) + except Exception as exc: + self._emit(EventType.ERROR, exc) + finally: + self._emit(EventType.CLOSE, None) + + def send_media(self, message: bytes) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a bytes. + """ + self._send(message) + + def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV1Finalize. + """ + self._send_model(message or ListenV1Finalize(type="Finalize")) + + def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV1CloseStream. + """ + self._send_model(message or ListenV1CloseStream(type="CloseStream")) + + def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV1KeepAlive. + """ + self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) + + def recv(self) -> V1SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + self._websocket.send(data) + + def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + self._send(data.dict()) diff --git a/src/deepgram/listen/v2/socket_client.py.bak b/src/deepgram/listen/v2/socket_client.py.bak new file mode 100644 index 00000000..d214f0f5 --- /dev/null +++ b/src/deepgram/listen/v2/socket_client.py.bak @@ -0,0 +1,220 @@ +# This file was auto-generated by Fern from our API Definition. + +import json +import logging +import typing + +import websockets.sync.connection as websockets_sync_connection +from ...core.events import EventEmitterMixin, EventType +from ...core.unchecked_base_model import construct_type +from .types.listen_v2close_stream import ListenV2CloseStream +from .types.listen_v2configure_failure import ListenV2ConfigureFailure +from .types.listen_v2connected import ListenV2Connected +from .types.listen_v2fatal_error import ListenV2FatalError +from .types.listen_v2turn_info import ListenV2TurnInfo + +try: + from websockets.legacy.client import WebSocketClientProtocol # type: ignore +except ImportError: + from websockets import WebSocketClientProtocol # type: ignore + +_logger = logging.getLogger(__name__) +V2SocketClientResponse = typing.Union[ + ListenV2Connected, ListenV2TurnInfo, typing.Any, ListenV2ConfigureFailure, ListenV2FatalError +] + + +class AsyncV2SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: WebSocketClientProtocol): + super().__init__() + self._websocket = websocket + + async def __aiter__(self): + async for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V2SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + async def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + await self._emit_async(EventType.OPEN, None) + try: + async for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + await self._emit_async(EventType.MESSAGE, parsed) + except Exception as exc: + await self._emit_async(EventType.ERROR, exc) + finally: + await self._emit_async(EventType.CLOSE, None) + + async def send_media(self, message: bytes) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a bytes. + """ + await self._send(message) + + async def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV2CloseStream. + """ + await self._send_model(message or ListenV2CloseStream(type="CloseStream")) + + async def send_configure(self, message: typing.Any) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a typing.Any. + """ + await self._send(message) + + async def recv(self) -> V2SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = await self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + async def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + await self._websocket.send(data) + + async def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + await self._send(data.dict()) + + +class V2SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: websockets_sync_connection.Connection): + super().__init__() + self._websocket = websocket + + def __iter__(self): + for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V2SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + self._emit(EventType.OPEN, None) + try: + for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + self._emit(EventType.MESSAGE, parsed) + except Exception as exc: + self._emit(EventType.ERROR, exc) + finally: + self._emit(EventType.CLOSE, None) + + def send_media(self, message: bytes) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a bytes. + """ + self._send(message) + + def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a ListenV2CloseStream. + """ + self._send_model(message or ListenV2CloseStream(type="CloseStream")) + + def send_configure(self, message: typing.Any) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a typing.Any. + """ + self._send(message) + + def recv(self) -> V2SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + self._websocket.send(data) + + def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + self._send(data.dict()) diff --git a/src/deepgram/speak/v1/socket_client.py.bak b/src/deepgram/speak/v1/socket_client.py.bak new file mode 100644 index 00000000..e3c28bb5 --- /dev/null +++ b/src/deepgram/speak/v1/socket_client.py.bak @@ -0,0 +1,235 @@ +# This file was auto-generated by Fern from our API Definition. + +import json +import logging +import typing + +import websockets.sync.connection as websockets_sync_connection +from ...core.events import EventEmitterMixin, EventType +from ...core.unchecked_base_model import construct_type +from .types.speak_v1clear import SpeakV1Clear +from .types.speak_v1cleared import SpeakV1Cleared +from .types.speak_v1close import SpeakV1Close +from .types.speak_v1flush import SpeakV1Flush +from .types.speak_v1flushed import SpeakV1Flushed +from .types.speak_v1metadata import SpeakV1Metadata +from .types.speak_v1text import SpeakV1Text +from .types.speak_v1warning import SpeakV1Warning + +try: + from websockets.legacy.client import WebSocketClientProtocol # type: ignore +except ImportError: + from websockets import WebSocketClientProtocol # type: ignore + +_logger = logging.getLogger(__name__) +V1SocketClientResponse = typing.Union[bytes, SpeakV1Metadata, SpeakV1Flushed, SpeakV1Cleared, SpeakV1Warning] + + +class AsyncV1SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: WebSocketClientProtocol): + super().__init__() + self._websocket = websocket + + async def __aiter__(self): + async for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + async def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + await self._emit_async(EventType.OPEN, None) + try: + async for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + await self._emit_async(EventType.MESSAGE, parsed) + except Exception as exc: + await self._emit_async(EventType.ERROR, exc) + finally: + await self._emit_async(EventType.CLOSE, None) + + async def send_text(self, message: SpeakV1Text) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Text. + """ + await self._send_model(message) + + async def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Flush. + """ + await self._send_model(message or SpeakV1Flush(type="Flush")) + + async def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Clear. + """ + await self._send_model(message or SpeakV1Clear(type="Clear")) + + async def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Close. + """ + await self._send_model(message or SpeakV1Close(type="Close")) + + async def recv(self) -> V1SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = await self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + async def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + await self._websocket.send(data) + + async def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + await self._send(data.dict()) + + +class V1SocketClient(EventEmitterMixin): + def __init__(self, *, websocket: websockets_sync_connection.Connection): + super().__init__() + self._websocket = websocket + + def __iter__(self): + for message in self._websocket: + if isinstance(message, bytes): + yield message + else: + try: + yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + + def start_listening(self): + """ + Start listening for messages on the websocket connection. + + Emits events in the following order: + - EventType.OPEN when connection is established + - EventType.MESSAGE for each message received + - EventType.ERROR if an error occurs + - EventType.CLOSE when connection is closed + """ + self._emit(EventType.OPEN, None) + try: + for raw_message in self._websocket: + if isinstance(raw_message, bytes): + parsed = raw_message + else: + json_data = json.loads(raw_message) + try: + parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning( + "Skipping unknown WebSocket message; update your SDK version to support new message types." + ) + continue + self._emit(EventType.MESSAGE, parsed) + except Exception as exc: + self._emit(EventType.ERROR, exc) + finally: + self._emit(EventType.CLOSE, None) + + def send_text(self, message: SpeakV1Text) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Text. + """ + self._send_model(message) + + def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Flush. + """ + self._send_model(message or SpeakV1Flush(type="Flush")) + + def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Clear. + """ + self._send_model(message or SpeakV1Clear(type="Clear")) + + def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: + """ + Send a message to the websocket connection. + The message will be sent as a SpeakV1Close. + """ + self._send_model(message or SpeakV1Close(type="Close")) + + def recv(self) -> V1SocketClientResponse: + """ + Receive a message from the websocket connection. + """ + data = self._websocket.recv() + if isinstance(data, bytes): + return data # type: ignore + json_data = json.loads(data) + try: + return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore + except Exception: + _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") + return json_data # type: ignore + + def _send(self, data: typing.Any) -> None: + """ + Send a message to the websocket connection. + """ + if isinstance(data, dict): + data = json.dumps(data) + self._websocket.send(data) + + def _send_model(self, data: typing.Any) -> None: + """ + Send a Pydantic model to the websocket connection. + """ + self._send(data.dict()) From 9bdeb197bbec9b9e45933c2a254108f3a736fa50 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 12:53:02 +0000 Subject: [PATCH 3/6] SDK regeneration --- .fern/metadata.json | 10 +- poetry.lock | 8 +- pyproject.toml | 4 +- src/deepgram/__init__.py | 15 +- src/deepgram/agent/__init__.py | 39 +- src/deepgram/agent/v1/__init__.py | 39 +- src/deepgram/agent/v1/requests/__init__.py | 22 +- .../agent/v1/requests/agent_v1history.py | 6 +- .../v1/requests/agent_v1history_content.py | 27 - .../agent_v1history_function_calls.py | 18 - .../requests/agent_v1inject_agent_message.py | 9 + ..._v1settings_agent_context_messages_item.py | 8 +- ...ent.py => conversation_history_message.py} | 2 +- ...ls.py => function_call_history_message.py} | 2 +- src/deepgram/agent/v1/socket_client.py | 40 +- src/deepgram/agent/v1/types/__init__.py | 23 +- .../agent/v1/types/agent_v1history.py | 6 +- .../agent/v1/types/agent_v1history_content.py | 38 -- .../types/agent_v1history_function_calls.py | 29 -- .../v1/types/agent_v1inject_agent_message.py | 9 + .../agent_v1inject_agent_message_behavior.py | 5 + ..._v1settings_agent_context_messages_item.py | 10 +- ...ent.py => conversation_history_message.py} | 2 +- ...ls.py => function_call_history_message.py} | 2 +- src/deepgram/core/client_wrapper.py | 4 +- src/deepgram/core/http_sse/_api.py | 78 ++- src/deepgram/listen/v1/socket_client.py | 30 +- src/deepgram/listen/v2/client.py | 21 + src/deepgram/listen/v2/raw_client.py | 21 + src/deepgram/listen/v2/socket_client.py | 30 +- .../manage/v1/projects/keys/client.py | 10 +- .../manage/v1/projects/keys/raw_client.py | 19 +- src/deepgram/requests/__init__.py | 6 + src/deepgram/requests/create_key_v1request.py | 5 + .../requests/listen_v2language_hint.py | 5 + src/deepgram/speak/v1/socket_client.py | 30 +- src/deepgram/types/__init__.py | 9 +- ...request_one.py => create_key_v1request.py} | 2 +- src/deepgram/types/listen_v2language_hint.py | 5 + tests/wire/test_read_v1_text.py | 6 +- uv.lock | 479 ------------------ 41 files changed, 312 insertions(+), 821 deletions(-) delete mode 100644 src/deepgram/agent/v1/requests/agent_v1history_content.py delete mode 100644 src/deepgram/agent/v1/requests/agent_v1history_function_calls.py rename src/deepgram/agent/v1/requests/{agent_v1settings_agent_context_messages_item_content.py => conversation_history_message.py} (87%) rename src/deepgram/agent/v1/requests/{agent_v1settings_agent_context_messages_item_function_calls.py => function_call_history_message.py} (86%) delete mode 100644 src/deepgram/agent/v1/types/agent_v1history_content.py delete mode 100644 src/deepgram/agent/v1/types/agent_v1history_function_calls.py create mode 100644 src/deepgram/agent/v1/types/agent_v1inject_agent_message_behavior.py rename src/deepgram/agent/v1/types/{agent_v1settings_agent_context_messages_item_content.py => conversation_history_message.py} (93%) rename src/deepgram/agent/v1/types/{agent_v1settings_agent_context_messages_item_function_calls.py => function_call_history_message.py} (92%) create mode 100644 src/deepgram/requests/create_key_v1request.py create mode 100644 src/deepgram/requests/listen_v2language_hint.py rename src/deepgram/types/{create_key_v1request_one.py => create_key_v1request.py} (63%) create mode 100644 src/deepgram/types/listen_v2language_hint.py delete mode 100644 uv.lock diff --git a/.fern/metadata.json b/.fern/metadata.json index 1bf9cd7e..770bf67f 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "4.92.0", + "cliVersion": "4.107.0", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "5.5.11", + "generatorVersion": "5.8.3", "generatorConfig": { "client": { "class_name": "BaseClient", @@ -16,10 +16,8 @@ "skip_validation": true } }, - "originGitCommit": "a11286b37e09a565312275eb0ee6b111fbdc5360", + "originGitCommit": "05bd7add608b322a6278fa20da22f2ed501d50ef", "originGitCommitIsDirty": true, "invokedBy": "manual", - "requestedVersion": null, - "ciProvider": null, - "sdkVersion": "6.1.2" + "sdkVersion": "7.0.1" } \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 5399b9ba..fb7ee00d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -881,13 +881,13 @@ files = [ [[package]] name = "packaging" -version = "26.1" +version = "26.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f"}, - {file = "packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de"}, + {file = "packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e"}, + {file = "packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"}, ] [[package]] @@ -1681,4 +1681,4 @@ aiohttp = ["aiohttp", "httpx-aiohttp"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "dd099e9cb03874e4a2fecf5b883fca8ac95981d50355ce3e88fa1f46d8e33b35" +content-hash = "d5bb491d83f174bf8206626bc5d74340716472be6f8907c2b3cfe7c8b8f0598a" diff --git a/pyproject.toml b/pyproject.toml index 6b35588d..f3e246f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ dynamic = ["version"] [tool.poetry] name = "deepgram-sdk" -version = "7.0.0" +version = "7.0.1" description = "" readme = "README.md" authors = [] @@ -53,7 +53,7 @@ pytest-asyncio = "^1.0.0" pytest-xdist = "^3.6.1" python-dateutil = "^2.9.0" types-python-dateutil = "^2.9.0.20240316" -urllib3 = ">=1.26.19,<2.0.0 || >=2.2.2,<3.0.0" +urllib3 = ">=2.6.3,<3.0.0" requests = "^2.33.0" types-requests = "^2.33.0" ruff = "==0.11.5" diff --git a/src/deepgram/__init__.py b/src/deepgram/__init__.py index 8f46a0b9..5a767214 100644 --- a/src/deepgram/__init__.py +++ b/src/deepgram/__init__.py @@ -38,7 +38,7 @@ CartesiaSpeakProviderModelId, CartesiaSpeakProviderVoice, CreateAgentConfigurationV1Response, - CreateKeyV1RequestOne, + CreateKeyV1Request, CreateKeyV1Response, CreateProjectDistributionCredentialsV1Response, CreateProjectDistributionCredentialsV1ResponseDistributionCredentials, @@ -163,6 +163,7 @@ ListenV2EotThreshold, ListenV2EotTimeoutMs, ListenV2Keyterm, + ListenV2LanguageHint, ListenV2MipOptOut, ListenV2Model, ListenV2SampleRate, @@ -263,6 +264,7 @@ CartesiaParams, CartesiaSpeakProviderVoiceParams, CreateAgentConfigurationV1ResponseParams, + CreateKeyV1RequestParams, CreateKeyV1ResponseParams, CreateProjectDistributionCredentialsV1ResponseDistributionCredentialsParams, CreateProjectDistributionCredentialsV1ResponseMemberParams, @@ -347,6 +349,7 @@ ListenV1ResponseResultsUtterancesItemWordsItemParams, ListenV1ResponseResultsUtterancesParams, ListenV2KeytermParams, + ListenV2LanguageHintParams, OpenAiSpeakProviderParams, OpenAiThinkProviderParams, ProjectRequestResponseParams, @@ -463,7 +466,8 @@ "CartesiaSpeakProviderVoiceParams": ".requests", "CreateAgentConfigurationV1Response": ".types", "CreateAgentConfigurationV1ResponseParams": ".requests", - "CreateKeyV1RequestOne": ".types", + "CreateKeyV1Request": ".types", + "CreateKeyV1RequestParams": ".requests", "CreateKeyV1Response": ".types", "CreateKeyV1ResponseParams": ".requests", "CreateProjectDistributionCredentialsV1Response": ".types", @@ -676,6 +680,8 @@ "ListenV2EotTimeoutMs": ".types", "ListenV2Keyterm": ".types", "ListenV2KeytermParams": ".requests", + "ListenV2LanguageHint": ".types", + "ListenV2LanguageHintParams": ".requests", "ListenV2MipOptOut": ".types", "ListenV2Model": ".types", "ListenV2SampleRate": ".types", @@ -895,7 +901,8 @@ def __dir__(): "CartesiaSpeakProviderVoiceParams", "CreateAgentConfigurationV1Response", "CreateAgentConfigurationV1ResponseParams", - "CreateKeyV1RequestOne", + "CreateKeyV1Request", + "CreateKeyV1RequestParams", "CreateKeyV1Response", "CreateKeyV1ResponseParams", "CreateProjectDistributionCredentialsV1Response", @@ -1108,6 +1115,8 @@ def __dir__(): "ListenV2EotTimeoutMs", "ListenV2Keyterm", "ListenV2KeytermParams", + "ListenV2LanguageHint", + "ListenV2LanguageHintParams", "ListenV2MipOptOut", "ListenV2Model", "ListenV2SampleRate", diff --git a/src/deepgram/agent/__init__.py b/src/deepgram/agent/__init__.py index 599c19b5..4c2fae13 100644 --- a/src/deepgram/agent/__init__.py +++ b/src/deepgram/agent/__init__.py @@ -24,15 +24,12 @@ AgentV1FunctionCallRequestFunctionsItemParams, AgentV1FunctionCallRequestParams, AgentV1History, - AgentV1HistoryContent, - AgentV1HistoryContentParams, AgentV1HistoryContentRole, - AgentV1HistoryFunctionCalls, AgentV1HistoryFunctionCallsFunctionCallsItem, AgentV1HistoryFunctionCallsFunctionCallsItemParams, - AgentV1HistoryFunctionCallsParams, AgentV1HistoryParams, AgentV1InjectAgentMessage, + AgentV1InjectAgentMessageBehavior, AgentV1InjectAgentMessageParams, AgentV1InjectUserMessage, AgentV1InjectUserMessageParams, @@ -50,13 +47,9 @@ AgentV1SettingsAgent, AgentV1SettingsAgentContext, AgentV1SettingsAgentContextMessagesItem, - AgentV1SettingsAgentContextMessagesItemContent, - AgentV1SettingsAgentContextMessagesItemContentParams, AgentV1SettingsAgentContextMessagesItemContentRole, - AgentV1SettingsAgentContextMessagesItemFunctionCalls, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams, - AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, AgentV1SettingsAgentContextMessagesItemParams, AgentV1SettingsAgentContextParams, AgentV1SettingsAgentListen, @@ -109,6 +102,10 @@ AgentV1WarningParams, AgentV1Welcome, AgentV1WelcomeParams, + ConversationHistoryMessage, + ConversationHistoryMessageParams, + FunctionCallHistoryMessage, + FunctionCallHistoryMessageParams, ) _dynamic_imports: typing.Dict[str, str] = { "AgentV1AgentAudioDone": ".v1", @@ -127,15 +124,12 @@ "AgentV1FunctionCallRequestFunctionsItemParams": ".v1", "AgentV1FunctionCallRequestParams": ".v1", "AgentV1History": ".v1", - "AgentV1HistoryContent": ".v1", - "AgentV1HistoryContentParams": ".v1", "AgentV1HistoryContentRole": ".v1", - "AgentV1HistoryFunctionCalls": ".v1", "AgentV1HistoryFunctionCallsFunctionCallsItem": ".v1", "AgentV1HistoryFunctionCallsFunctionCallsItemParams": ".v1", - "AgentV1HistoryFunctionCallsParams": ".v1", "AgentV1HistoryParams": ".v1", "AgentV1InjectAgentMessage": ".v1", + "AgentV1InjectAgentMessageBehavior": ".v1", "AgentV1InjectAgentMessageParams": ".v1", "AgentV1InjectUserMessage": ".v1", "AgentV1InjectUserMessageParams": ".v1", @@ -153,13 +147,9 @@ "AgentV1SettingsAgent": ".v1", "AgentV1SettingsAgentContext": ".v1", "AgentV1SettingsAgentContextMessagesItem": ".v1", - "AgentV1SettingsAgentContextMessagesItemContent": ".v1", - "AgentV1SettingsAgentContextMessagesItemContentParams": ".v1", "AgentV1SettingsAgentContextMessagesItemContentRole": ".v1", - "AgentV1SettingsAgentContextMessagesItemFunctionCalls": ".v1", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem": ".v1", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams": ".v1", - "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams": ".v1", "AgentV1SettingsAgentContextMessagesItemParams": ".v1", "AgentV1SettingsAgentContextParams": ".v1", "AgentV1SettingsAgentListen": ".v1", @@ -212,6 +202,10 @@ "AgentV1WarningParams": ".v1", "AgentV1Welcome": ".v1", "AgentV1WelcomeParams": ".v1", + "ConversationHistoryMessage": ".v1", + "ConversationHistoryMessageParams": ".v1", + "FunctionCallHistoryMessage": ".v1", + "FunctionCallHistoryMessageParams": ".v1", "v1": ".v1", } @@ -254,15 +248,12 @@ def __dir__(): "AgentV1FunctionCallRequestFunctionsItemParams", "AgentV1FunctionCallRequestParams", "AgentV1History", - "AgentV1HistoryContent", - "AgentV1HistoryContentParams", "AgentV1HistoryContentRole", - "AgentV1HistoryFunctionCalls", "AgentV1HistoryFunctionCallsFunctionCallsItem", "AgentV1HistoryFunctionCallsFunctionCallsItemParams", - "AgentV1HistoryFunctionCallsParams", "AgentV1HistoryParams", "AgentV1InjectAgentMessage", + "AgentV1InjectAgentMessageBehavior", "AgentV1InjectAgentMessageParams", "AgentV1InjectUserMessage", "AgentV1InjectUserMessageParams", @@ -280,13 +271,9 @@ def __dir__(): "AgentV1SettingsAgent", "AgentV1SettingsAgentContext", "AgentV1SettingsAgentContextMessagesItem", - "AgentV1SettingsAgentContextMessagesItemContent", - "AgentV1SettingsAgentContextMessagesItemContentParams", "AgentV1SettingsAgentContextMessagesItemContentRole", - "AgentV1SettingsAgentContextMessagesItemFunctionCalls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams", - "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams", "AgentV1SettingsAgentContextMessagesItemParams", "AgentV1SettingsAgentContextParams", "AgentV1SettingsAgentListen", @@ -339,5 +326,9 @@ def __dir__(): "AgentV1WarningParams", "AgentV1Welcome", "AgentV1WelcomeParams", + "ConversationHistoryMessage", + "ConversationHistoryMessageParams", + "FunctionCallHistoryMessage", + "FunctionCallHistoryMessageParams", "v1", ] diff --git a/src/deepgram/agent/v1/__init__.py b/src/deepgram/agent/v1/__init__.py index 084cb184..8e85426d 100644 --- a/src/deepgram/agent/v1/__init__.py +++ b/src/deepgram/agent/v1/__init__.py @@ -16,11 +16,10 @@ AgentV1FunctionCallRequest, AgentV1FunctionCallRequestFunctionsItem, AgentV1History, - AgentV1HistoryContent, AgentV1HistoryContentRole, - AgentV1HistoryFunctionCalls, AgentV1HistoryFunctionCallsFunctionCallsItem, AgentV1InjectAgentMessage, + AgentV1InjectAgentMessageBehavior, AgentV1InjectUserMessage, AgentV1InjectionRefused, AgentV1KeepAlive, @@ -31,9 +30,7 @@ AgentV1SettingsAgent, AgentV1SettingsAgentContext, AgentV1SettingsAgentContextMessagesItem, - AgentV1SettingsAgentContextMessagesItemContent, AgentV1SettingsAgentContextMessagesItemContentRole, - AgentV1SettingsAgentContextMessagesItemFunctionCalls, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem, AgentV1SettingsAgentListen, AgentV1SettingsAgentListenProvider, @@ -60,6 +57,8 @@ AgentV1UserStartedSpeaking, AgentV1Warning, AgentV1Welcome, + ConversationHistoryMessage, + FunctionCallHistoryMessage, ) from . import settings from .requests import ( @@ -70,9 +69,7 @@ AgentV1ErrorParams, AgentV1FunctionCallRequestFunctionsItemParams, AgentV1FunctionCallRequestParams, - AgentV1HistoryContentParams, AgentV1HistoryFunctionCallsFunctionCallsItemParams, - AgentV1HistoryFunctionCallsParams, AgentV1HistoryParams, AgentV1InjectAgentMessageParams, AgentV1InjectUserMessageParams, @@ -81,9 +78,7 @@ AgentV1PromptUpdatedParams, AgentV1ReceiveFunctionCallResponseParams, AgentV1SendFunctionCallResponseParams, - AgentV1SettingsAgentContextMessagesItemContentParams, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams, - AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, AgentV1SettingsAgentContextMessagesItemParams, AgentV1SettingsAgentContextParams, AgentV1SettingsAgentListenParams, @@ -111,6 +106,8 @@ AgentV1UserStartedSpeakingParams, AgentV1WarningParams, AgentV1WelcomeParams, + ConversationHistoryMessageParams, + FunctionCallHistoryMessageParams, ) _dynamic_imports: typing.Dict[str, str] = { "AgentV1AgentAudioDone": ".types", @@ -129,15 +126,12 @@ "AgentV1FunctionCallRequestFunctionsItemParams": ".requests", "AgentV1FunctionCallRequestParams": ".requests", "AgentV1History": ".types", - "AgentV1HistoryContent": ".types", - "AgentV1HistoryContentParams": ".requests", "AgentV1HistoryContentRole": ".types", - "AgentV1HistoryFunctionCalls": ".types", "AgentV1HistoryFunctionCallsFunctionCallsItem": ".types", "AgentV1HistoryFunctionCallsFunctionCallsItemParams": ".requests", - "AgentV1HistoryFunctionCallsParams": ".requests", "AgentV1HistoryParams": ".requests", "AgentV1InjectAgentMessage": ".types", + "AgentV1InjectAgentMessageBehavior": ".types", "AgentV1InjectAgentMessageParams": ".requests", "AgentV1InjectUserMessage": ".types", "AgentV1InjectUserMessageParams": ".requests", @@ -155,13 +149,9 @@ "AgentV1SettingsAgent": ".types", "AgentV1SettingsAgentContext": ".types", "AgentV1SettingsAgentContextMessagesItem": ".types", - "AgentV1SettingsAgentContextMessagesItemContent": ".types", - "AgentV1SettingsAgentContextMessagesItemContentParams": ".requests", "AgentV1SettingsAgentContextMessagesItemContentRole": ".types", - "AgentV1SettingsAgentContextMessagesItemFunctionCalls": ".types", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem": ".types", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams": ".requests", - "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams": ".requests", "AgentV1SettingsAgentContextMessagesItemParams": ".requests", "AgentV1SettingsAgentContextParams": ".requests", "AgentV1SettingsAgentListen": ".types", @@ -214,6 +204,10 @@ "AgentV1WarningParams": ".requests", "AgentV1Welcome": ".types", "AgentV1WelcomeParams": ".requests", + "ConversationHistoryMessage": ".types", + "ConversationHistoryMessageParams": ".requests", + "FunctionCallHistoryMessage": ".types", + "FunctionCallHistoryMessageParams": ".requests", "settings": ".settings", } @@ -256,15 +250,12 @@ def __dir__(): "AgentV1FunctionCallRequestFunctionsItemParams", "AgentV1FunctionCallRequestParams", "AgentV1History", - "AgentV1HistoryContent", - "AgentV1HistoryContentParams", "AgentV1HistoryContentRole", - "AgentV1HistoryFunctionCalls", "AgentV1HistoryFunctionCallsFunctionCallsItem", "AgentV1HistoryFunctionCallsFunctionCallsItemParams", - "AgentV1HistoryFunctionCallsParams", "AgentV1HistoryParams", "AgentV1InjectAgentMessage", + "AgentV1InjectAgentMessageBehavior", "AgentV1InjectAgentMessageParams", "AgentV1InjectUserMessage", "AgentV1InjectUserMessageParams", @@ -282,13 +273,9 @@ def __dir__(): "AgentV1SettingsAgent", "AgentV1SettingsAgentContext", "AgentV1SettingsAgentContextMessagesItem", - "AgentV1SettingsAgentContextMessagesItemContent", - "AgentV1SettingsAgentContextMessagesItemContentParams", "AgentV1SettingsAgentContextMessagesItemContentRole", - "AgentV1SettingsAgentContextMessagesItemFunctionCalls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams", - "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams", "AgentV1SettingsAgentContextMessagesItemParams", "AgentV1SettingsAgentContextParams", "AgentV1SettingsAgentListen", @@ -341,5 +328,9 @@ def __dir__(): "AgentV1WarningParams", "AgentV1Welcome", "AgentV1WelcomeParams", + "ConversationHistoryMessage", + "ConversationHistoryMessageParams", + "FunctionCallHistoryMessage", + "FunctionCallHistoryMessageParams", "settings", ] diff --git a/src/deepgram/agent/v1/requests/__init__.py b/src/deepgram/agent/v1/requests/__init__.py index a6d338c1..3eb12d59 100644 --- a/src/deepgram/agent/v1/requests/__init__.py +++ b/src/deepgram/agent/v1/requests/__init__.py @@ -14,8 +14,6 @@ from .agent_v1function_call_request import AgentV1FunctionCallRequestParams from .agent_v1function_call_request_functions_item import AgentV1FunctionCallRequestFunctionsItemParams from .agent_v1history import AgentV1HistoryParams - from .agent_v1history_content import AgentV1HistoryContentParams - from .agent_v1history_function_calls import AgentV1HistoryFunctionCallsParams from .agent_v1history_function_calls_function_calls_item import AgentV1HistoryFunctionCallsFunctionCallsItemParams from .agent_v1inject_agent_message import AgentV1InjectAgentMessageParams from .agent_v1inject_user_message import AgentV1InjectUserMessageParams @@ -28,12 +26,6 @@ from .agent_v1settings_agent import AgentV1SettingsAgentParams from .agent_v1settings_agent_context import AgentV1SettingsAgentContextParams from .agent_v1settings_agent_context_messages_item import AgentV1SettingsAgentContextMessagesItemParams - from .agent_v1settings_agent_context_messages_item_content import ( - AgentV1SettingsAgentContextMessagesItemContentParams, - ) - from .agent_v1settings_agent_context_messages_item_function_calls import ( - AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, - ) from .agent_v1settings_agent_context_messages_item_function_calls_function_calls_item import ( AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams, ) @@ -62,6 +54,8 @@ from .agent_v1user_started_speaking import AgentV1UserStartedSpeakingParams from .agent_v1warning import AgentV1WarningParams from .agent_v1welcome import AgentV1WelcomeParams + from .conversation_history_message import ConversationHistoryMessageParams + from .function_call_history_message import FunctionCallHistoryMessageParams _dynamic_imports: typing.Dict[str, str] = { "AgentV1AgentAudioDoneParams": ".agent_v1agent_audio_done", "AgentV1AgentStartedSpeakingParams": ".agent_v1agent_started_speaking", @@ -70,9 +64,7 @@ "AgentV1ErrorParams": ".agent_v1error", "AgentV1FunctionCallRequestFunctionsItemParams": ".agent_v1function_call_request_functions_item", "AgentV1FunctionCallRequestParams": ".agent_v1function_call_request", - "AgentV1HistoryContentParams": ".agent_v1history_content", "AgentV1HistoryFunctionCallsFunctionCallsItemParams": ".agent_v1history_function_calls_function_calls_item", - "AgentV1HistoryFunctionCallsParams": ".agent_v1history_function_calls", "AgentV1HistoryParams": ".agent_v1history", "AgentV1InjectAgentMessageParams": ".agent_v1inject_agent_message", "AgentV1InjectUserMessageParams": ".agent_v1inject_user_message", @@ -81,9 +73,7 @@ "AgentV1PromptUpdatedParams": ".agent_v1prompt_updated", "AgentV1ReceiveFunctionCallResponseParams": ".agent_v1receive_function_call_response", "AgentV1SendFunctionCallResponseParams": ".agent_v1send_function_call_response", - "AgentV1SettingsAgentContextMessagesItemContentParams": ".agent_v1settings_agent_context_messages_item_content", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams": ".agent_v1settings_agent_context_messages_item_function_calls_function_calls_item", - "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams": ".agent_v1settings_agent_context_messages_item_function_calls", "AgentV1SettingsAgentContextMessagesItemParams": ".agent_v1settings_agent_context_messages_item", "AgentV1SettingsAgentContextParams": ".agent_v1settings_agent_context", "AgentV1SettingsAgentListenParams": ".agent_v1settings_agent_listen", @@ -111,6 +101,8 @@ "AgentV1UserStartedSpeakingParams": ".agent_v1user_started_speaking", "AgentV1WarningParams": ".agent_v1warning", "AgentV1WelcomeParams": ".agent_v1welcome", + "ConversationHistoryMessageParams": ".conversation_history_message", + "FunctionCallHistoryMessageParams": ".function_call_history_message", } @@ -143,9 +135,7 @@ def __dir__(): "AgentV1ErrorParams", "AgentV1FunctionCallRequestFunctionsItemParams", "AgentV1FunctionCallRequestParams", - "AgentV1HistoryContentParams", "AgentV1HistoryFunctionCallsFunctionCallsItemParams", - "AgentV1HistoryFunctionCallsParams", "AgentV1HistoryParams", "AgentV1InjectAgentMessageParams", "AgentV1InjectUserMessageParams", @@ -154,9 +144,7 @@ def __dir__(): "AgentV1PromptUpdatedParams", "AgentV1ReceiveFunctionCallResponseParams", "AgentV1SendFunctionCallResponseParams", - "AgentV1SettingsAgentContextMessagesItemContentParams", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams", - "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams", "AgentV1SettingsAgentContextMessagesItemParams", "AgentV1SettingsAgentContextParams", "AgentV1SettingsAgentListenParams", @@ -184,4 +172,6 @@ def __dir__(): "AgentV1UserStartedSpeakingParams", "AgentV1WarningParams", "AgentV1WelcomeParams", + "ConversationHistoryMessageParams", + "FunctionCallHistoryMessageParams", ] diff --git a/src/deepgram/agent/v1/requests/agent_v1history.py b/src/deepgram/agent/v1/requests/agent_v1history.py index 181bfdfd..a0f8a56b 100644 --- a/src/deepgram/agent/v1/requests/agent_v1history.py +++ b/src/deepgram/agent/v1/requests/agent_v1history.py @@ -2,7 +2,7 @@ import typing -from .agent_v1history_content import AgentV1HistoryContentParams -from .agent_v1history_function_calls import AgentV1HistoryFunctionCallsParams +from .conversation_history_message import ConversationHistoryMessageParams +from .function_call_history_message import FunctionCallHistoryMessageParams -AgentV1HistoryParams = typing.Union[AgentV1HistoryContentParams, AgentV1HistoryFunctionCallsParams] +AgentV1HistoryParams = typing.Union[ConversationHistoryMessageParams, FunctionCallHistoryMessageParams] diff --git a/src/deepgram/agent/v1/requests/agent_v1history_content.py b/src/deepgram/agent/v1/requests/agent_v1history_content.py deleted file mode 100644 index 80dca1ae..00000000 --- a/src/deepgram/agent/v1/requests/agent_v1history_content.py +++ /dev/null @@ -1,27 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import typing_extensions -from ..types.agent_v1history_content_role import AgentV1HistoryContentRole - - -class AgentV1HistoryContentParams(typing_extensions.TypedDict): - """ - Conversation text as part of the conversation history - """ - - type: typing.Literal["History"] - """ - Message type identifier for conversation text - """ - - role: AgentV1HistoryContentRole - """ - Identifies who spoke the statement - """ - - content: str - """ - The actual statement that was spoken - """ diff --git a/src/deepgram/agent/v1/requests/agent_v1history_function_calls.py b/src/deepgram/agent/v1/requests/agent_v1history_function_calls.py deleted file mode 100644 index 3695cfc2..00000000 --- a/src/deepgram/agent/v1/requests/agent_v1history_function_calls.py +++ /dev/null @@ -1,18 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import typing_extensions -from .agent_v1history_function_calls_function_calls_item import AgentV1HistoryFunctionCallsFunctionCallsItemParams - - -class AgentV1HistoryFunctionCallsParams(typing_extensions.TypedDict): - """ - Client-side or server-side function call request and response as part of the conversation history - """ - - type: typing.Literal["History"] - function_calls: typing.Sequence[AgentV1HistoryFunctionCallsFunctionCallsItemParams] - """ - List of function call objects - """ diff --git a/src/deepgram/agent/v1/requests/agent_v1inject_agent_message.py b/src/deepgram/agent/v1/requests/agent_v1inject_agent_message.py index 8fb718bd..304cf18b 100644 --- a/src/deepgram/agent/v1/requests/agent_v1inject_agent_message.py +++ b/src/deepgram/agent/v1/requests/agent_v1inject_agent_message.py @@ -3,6 +3,7 @@ import typing import typing_extensions +from ..types.agent_v1inject_agent_message_behavior import AgentV1InjectAgentMessageBehavior class AgentV1InjectAgentMessageParams(typing_extensions.TypedDict): @@ -15,3 +16,11 @@ class AgentV1InjectAgentMessageParams(typing_extensions.TypedDict): """ The statement that the agent should say """ + + behavior: typing_extensions.NotRequired[AgentV1InjectAgentMessageBehavior] + """ + Controls how the injection interacts with any in-progress user or agent turn. + + * `default` — The agent speaks only if neither the user nor the agent is mid-turn. If a turn is in progress, the server replies with `InjectionRefused`. + * `queue` — The message is appended after any already-queued `ConversationText` without interrupting the current agent turn or think response. If nothing is queued, the message plays immediately. + """ diff --git a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item.py b/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item.py index cf31d658..a9fd9f6b 100644 --- a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item.py +++ b/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item.py @@ -2,11 +2,9 @@ import typing -from .agent_v1settings_agent_context_messages_item_content import AgentV1SettingsAgentContextMessagesItemContentParams -from .agent_v1settings_agent_context_messages_item_function_calls import ( - AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, -) +from .conversation_history_message import ConversationHistoryMessageParams +from .function_call_history_message import FunctionCallHistoryMessageParams AgentV1SettingsAgentContextMessagesItemParams = typing.Union[ - AgentV1SettingsAgentContextMessagesItemContentParams, AgentV1SettingsAgentContextMessagesItemFunctionCallsParams + ConversationHistoryMessageParams, FunctionCallHistoryMessageParams ] diff --git a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py b/src/deepgram/agent/v1/requests/conversation_history_message.py similarity index 87% rename from src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py rename to src/deepgram/agent/v1/requests/conversation_history_message.py index 1a541ffc..93b350d7 100644 --- a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py +++ b/src/deepgram/agent/v1/requests/conversation_history_message.py @@ -8,7 +8,7 @@ ) -class AgentV1SettingsAgentContextMessagesItemContentParams(typing_extensions.TypedDict): +class ConversationHistoryMessageParams(typing_extensions.TypedDict): """ Conversation text as part of the conversation history """ diff --git a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py b/src/deepgram/agent/v1/requests/function_call_history_message.py similarity index 86% rename from src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py rename to src/deepgram/agent/v1/requests/function_call_history_message.py index cdc5733c..9bc1d14e 100644 --- a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py +++ b/src/deepgram/agent/v1/requests/function_call_history_message.py @@ -8,7 +8,7 @@ ) -class AgentV1SettingsAgentContextMessagesItemFunctionCallsParams(typing_extensions.TypedDict): +class FunctionCallHistoryMessageParams(typing_extensions.TypedDict): """ Client-side or server-side function call request and response as part of the conversation history """ diff --git a/src/deepgram/agent/v1/socket_client.py b/src/deepgram/agent/v1/socket_client.py index 17c3d0d2..b75080a7 100644 --- a/src/deepgram/agent/v1/socket_client.py +++ b/src/deepgram/agent/v1/socket_client.py @@ -3,7 +3,9 @@ import json import logging import typing +from json.decoder import JSONDecodeError +import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type @@ -38,28 +40,6 @@ from websockets import WebSocketClientProtocol # type: ignore _logger = logging.getLogger(__name__) - - -def _sanitize_numeric_types(obj: typing.Any) -> typing.Any: - """ - Recursively convert float values that are whole numbers to int. - - Workaround for Fern-generated models that type integer API fields - (like sample_rate) as float, causing JSON serialization to produce - values like 44100.0 instead of 44100. The Deepgram API rejects - float representations of integer fields. - - See: https://github.com/deepgram/internal-api-specs/issues/205 - """ - if isinstance(obj, dict): - return {k: _sanitize_numeric_types(v) for k, v in obj.items()} - elif isinstance(obj, list): - return [_sanitize_numeric_types(item) for item in obj] - elif isinstance(obj, float) and obj.is_integer(): - return int(obj) - return obj - - V1SocketClientResponse = typing.Union[ AgentV1ReceiveFunctionCallResponse, AgentV1PromptUpdated, @@ -124,7 +104,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -164,12 +144,12 @@ async def send_function_call_response(self, message: AgentV1SendFunctionCallResp """ await self._send_model(message) - async def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: + async def send_keep_alive(self, message: AgentV1KeepAlive) -> None: """ Send a message to the websocket connection. The message will be sent as a AgentV1KeepAlive. """ - await self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) + await self._send_model(message) async def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: """ @@ -218,7 +198,7 @@ async def _send_model(self, data: typing.Any) -> None: """ Send a Pydantic model to the websocket connection. """ - await self._send(_sanitize_numeric_types(data.dict())) + await self._send(data.dict()) class V1SocketClient(EventEmitterMixin): @@ -264,7 +244,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -304,12 +284,12 @@ def send_function_call_response(self, message: AgentV1SendFunctionCallResponse) """ self._send_model(message) - def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: + def send_keep_alive(self, message: AgentV1KeepAlive) -> None: """ Send a message to the websocket connection. The message will be sent as a AgentV1KeepAlive. """ - self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) + self._send_model(message) def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: """ @@ -358,4 +338,4 @@ def _send_model(self, data: typing.Any) -> None: """ Send a Pydantic model to the websocket connection. """ - self._send(_sanitize_numeric_types(data.dict())) + self._send(data.dict()) diff --git a/src/deepgram/agent/v1/types/__init__.py b/src/deepgram/agent/v1/types/__init__.py index efadce6c..15118c7a 100644 --- a/src/deepgram/agent/v1/types/__init__.py +++ b/src/deepgram/agent/v1/types/__init__.py @@ -15,11 +15,10 @@ from .agent_v1function_call_request import AgentV1FunctionCallRequest from .agent_v1function_call_request_functions_item import AgentV1FunctionCallRequestFunctionsItem from .agent_v1history import AgentV1History - from .agent_v1history_content import AgentV1HistoryContent from .agent_v1history_content_role import AgentV1HistoryContentRole - from .agent_v1history_function_calls import AgentV1HistoryFunctionCalls from .agent_v1history_function_calls_function_calls_item import AgentV1HistoryFunctionCallsFunctionCallsItem from .agent_v1inject_agent_message import AgentV1InjectAgentMessage + from .agent_v1inject_agent_message_behavior import AgentV1InjectAgentMessageBehavior from .agent_v1inject_user_message import AgentV1InjectUserMessage from .agent_v1injection_refused import AgentV1InjectionRefused from .agent_v1keep_alive import AgentV1KeepAlive @@ -30,13 +29,9 @@ from .agent_v1settings_agent import AgentV1SettingsAgent from .agent_v1settings_agent_context import AgentV1SettingsAgentContext from .agent_v1settings_agent_context_messages_item import AgentV1SettingsAgentContextMessagesItem - from .agent_v1settings_agent_context_messages_item_content import AgentV1SettingsAgentContextMessagesItemContent from .agent_v1settings_agent_context_messages_item_content_role import ( AgentV1SettingsAgentContextMessagesItemContentRole, ) - from .agent_v1settings_agent_context_messages_item_function_calls import ( - AgentV1SettingsAgentContextMessagesItemFunctionCalls, - ) from .agent_v1settings_agent_context_messages_item_function_calls_function_calls_item import ( AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem, ) @@ -67,6 +62,8 @@ from .agent_v1user_started_speaking import AgentV1UserStartedSpeaking from .agent_v1warning import AgentV1Warning from .agent_v1welcome import AgentV1Welcome + from .conversation_history_message import ConversationHistoryMessage + from .function_call_history_message import FunctionCallHistoryMessage _dynamic_imports: typing.Dict[str, str] = { "AgentV1AgentAudioDone": ".agent_v1agent_audio_done", "AgentV1AgentStartedSpeaking": ".agent_v1agent_started_speaking", @@ -77,11 +74,10 @@ "AgentV1FunctionCallRequest": ".agent_v1function_call_request", "AgentV1FunctionCallRequestFunctionsItem": ".agent_v1function_call_request_functions_item", "AgentV1History": ".agent_v1history", - "AgentV1HistoryContent": ".agent_v1history_content", "AgentV1HistoryContentRole": ".agent_v1history_content_role", - "AgentV1HistoryFunctionCalls": ".agent_v1history_function_calls", "AgentV1HistoryFunctionCallsFunctionCallsItem": ".agent_v1history_function_calls_function_calls_item", "AgentV1InjectAgentMessage": ".agent_v1inject_agent_message", + "AgentV1InjectAgentMessageBehavior": ".agent_v1inject_agent_message_behavior", "AgentV1InjectUserMessage": ".agent_v1inject_user_message", "AgentV1InjectionRefused": ".agent_v1injection_refused", "AgentV1KeepAlive": ".agent_v1keep_alive", @@ -92,9 +88,7 @@ "AgentV1SettingsAgent": ".agent_v1settings_agent", "AgentV1SettingsAgentContext": ".agent_v1settings_agent_context", "AgentV1SettingsAgentContextMessagesItem": ".agent_v1settings_agent_context_messages_item", - "AgentV1SettingsAgentContextMessagesItemContent": ".agent_v1settings_agent_context_messages_item_content", "AgentV1SettingsAgentContextMessagesItemContentRole": ".agent_v1settings_agent_context_messages_item_content_role", - "AgentV1SettingsAgentContextMessagesItemFunctionCalls": ".agent_v1settings_agent_context_messages_item_function_calls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem": ".agent_v1settings_agent_context_messages_item_function_calls_function_calls_item", "AgentV1SettingsAgentListen": ".agent_v1settings_agent_listen", "AgentV1SettingsAgentListenProvider": ".agent_v1settings_agent_listen_provider", @@ -121,6 +115,8 @@ "AgentV1UserStartedSpeaking": ".agent_v1user_started_speaking", "AgentV1Warning": ".agent_v1warning", "AgentV1Welcome": ".agent_v1welcome", + "ConversationHistoryMessage": ".conversation_history_message", + "FunctionCallHistoryMessage": ".function_call_history_message", } @@ -155,11 +151,10 @@ def __dir__(): "AgentV1FunctionCallRequest", "AgentV1FunctionCallRequestFunctionsItem", "AgentV1History", - "AgentV1HistoryContent", "AgentV1HistoryContentRole", - "AgentV1HistoryFunctionCalls", "AgentV1HistoryFunctionCallsFunctionCallsItem", "AgentV1InjectAgentMessage", + "AgentV1InjectAgentMessageBehavior", "AgentV1InjectUserMessage", "AgentV1InjectionRefused", "AgentV1KeepAlive", @@ -170,9 +165,7 @@ def __dir__(): "AgentV1SettingsAgent", "AgentV1SettingsAgentContext", "AgentV1SettingsAgentContextMessagesItem", - "AgentV1SettingsAgentContextMessagesItemContent", "AgentV1SettingsAgentContextMessagesItemContentRole", - "AgentV1SettingsAgentContextMessagesItemFunctionCalls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem", "AgentV1SettingsAgentListen", "AgentV1SettingsAgentListenProvider", @@ -199,4 +192,6 @@ def __dir__(): "AgentV1UserStartedSpeaking", "AgentV1Warning", "AgentV1Welcome", + "ConversationHistoryMessage", + "FunctionCallHistoryMessage", ] diff --git a/src/deepgram/agent/v1/types/agent_v1history.py b/src/deepgram/agent/v1/types/agent_v1history.py index a3164360..40f2aba6 100644 --- a/src/deepgram/agent/v1/types/agent_v1history.py +++ b/src/deepgram/agent/v1/types/agent_v1history.py @@ -2,7 +2,7 @@ import typing -from .agent_v1history_content import AgentV1HistoryContent -from .agent_v1history_function_calls import AgentV1HistoryFunctionCalls +from .conversation_history_message import ConversationHistoryMessage +from .function_call_history_message import FunctionCallHistoryMessage -AgentV1History = typing.Union[AgentV1HistoryContent, AgentV1HistoryFunctionCalls] +AgentV1History = typing.Union[ConversationHistoryMessage, FunctionCallHistoryMessage] diff --git a/src/deepgram/agent/v1/types/agent_v1history_content.py b/src/deepgram/agent/v1/types/agent_v1history_content.py deleted file mode 100644 index 5c8a9c3a..00000000 --- a/src/deepgram/agent/v1/types/agent_v1history_content.py +++ /dev/null @@ -1,38 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ....core.pydantic_utilities import IS_PYDANTIC_V2 -from ....core.unchecked_base_model import UncheckedBaseModel -from .agent_v1history_content_role import AgentV1HistoryContentRole - - -class AgentV1HistoryContent(UncheckedBaseModel): - """ - Conversation text as part of the conversation history - """ - - type: typing.Literal["History"] = pydantic.Field(default="History") - """ - Message type identifier for conversation text - """ - - role: AgentV1HistoryContentRole = pydantic.Field() - """ - Identifies who spoke the statement - """ - - content: str = pydantic.Field() - """ - The actual statement that was spoken - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/deepgram/agent/v1/types/agent_v1history_function_calls.py b/src/deepgram/agent/v1/types/agent_v1history_function_calls.py deleted file mode 100644 index 66f9c34f..00000000 --- a/src/deepgram/agent/v1/types/agent_v1history_function_calls.py +++ /dev/null @@ -1,29 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ....core.pydantic_utilities import IS_PYDANTIC_V2 -from ....core.unchecked_base_model import UncheckedBaseModel -from .agent_v1history_function_calls_function_calls_item import AgentV1HistoryFunctionCallsFunctionCallsItem - - -class AgentV1HistoryFunctionCalls(UncheckedBaseModel): - """ - Client-side or server-side function call request and response as part of the conversation history - """ - - type: typing.Literal["History"] = "History" - function_calls: typing.List[AgentV1HistoryFunctionCallsFunctionCallsItem] = pydantic.Field() - """ - List of function call objects - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/deepgram/agent/v1/types/agent_v1inject_agent_message.py b/src/deepgram/agent/v1/types/agent_v1inject_agent_message.py index a2ca5886..a2a1c61d 100644 --- a/src/deepgram/agent/v1/types/agent_v1inject_agent_message.py +++ b/src/deepgram/agent/v1/types/agent_v1inject_agent_message.py @@ -5,6 +5,7 @@ import pydantic from ....core.pydantic_utilities import IS_PYDANTIC_V2 from ....core.unchecked_base_model import UncheckedBaseModel +from .agent_v1inject_agent_message_behavior import AgentV1InjectAgentMessageBehavior class AgentV1InjectAgentMessage(UncheckedBaseModel): @@ -18,6 +19,14 @@ class AgentV1InjectAgentMessage(UncheckedBaseModel): The statement that the agent should say """ + behavior: typing.Optional[AgentV1InjectAgentMessageBehavior] = pydantic.Field(default=None) + """ + Controls how the injection interacts with any in-progress user or agent turn. + + * `default` — The agent speaks only if neither the user nor the agent is mid-turn. If a turn is in progress, the server replies with `InjectionRefused`. + * `queue` — The message is appended after any already-queued `ConversationText` without interrupting the current agent turn or think response. If nothing is queued, the message plays immediately. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/deepgram/agent/v1/types/agent_v1inject_agent_message_behavior.py b/src/deepgram/agent/v1/types/agent_v1inject_agent_message_behavior.py new file mode 100644 index 00000000..9c610dc4 --- /dev/null +++ b/src/deepgram/agent/v1/types/agent_v1inject_agent_message_behavior.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentV1InjectAgentMessageBehavior = typing.Union[typing.Literal["default", "queue"], typing.Any] diff --git a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item.py b/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item.py index 2061fd2d..6fb14531 100644 --- a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item.py +++ b/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item.py @@ -2,11 +2,7 @@ import typing -from .agent_v1settings_agent_context_messages_item_content import AgentV1SettingsAgentContextMessagesItemContent -from .agent_v1settings_agent_context_messages_item_function_calls import ( - AgentV1SettingsAgentContextMessagesItemFunctionCalls, -) +from .conversation_history_message import ConversationHistoryMessage +from .function_call_history_message import FunctionCallHistoryMessage -AgentV1SettingsAgentContextMessagesItem = typing.Union[ - AgentV1SettingsAgentContextMessagesItemContent, AgentV1SettingsAgentContextMessagesItemFunctionCalls -] +AgentV1SettingsAgentContextMessagesItem = typing.Union[ConversationHistoryMessage, FunctionCallHistoryMessage] diff --git a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py b/src/deepgram/agent/v1/types/conversation_history_message.py similarity index 93% rename from src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py rename to src/deepgram/agent/v1/types/conversation_history_message.py index c1ad74ec..bce234b5 100644 --- a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py +++ b/src/deepgram/agent/v1/types/conversation_history_message.py @@ -10,7 +10,7 @@ ) -class AgentV1SettingsAgentContextMessagesItemContent(UncheckedBaseModel): +class ConversationHistoryMessage(UncheckedBaseModel): """ Conversation text as part of the conversation history """ diff --git a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py b/src/deepgram/agent/v1/types/function_call_history_message.py similarity index 92% rename from src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py rename to src/deepgram/agent/v1/types/function_call_history_message.py index dd693535..68c6e64f 100644 --- a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py +++ b/src/deepgram/agent/v1/types/function_call_history_message.py @@ -10,7 +10,7 @@ ) -class AgentV1SettingsAgentContextMessagesItemFunctionCalls(UncheckedBaseModel): +class FunctionCallHistoryMessage(UncheckedBaseModel): """ Client-side or server-side function call request and response as part of the conversation history """ diff --git a/src/deepgram/core/client_wrapper.py b/src/deepgram/core/client_wrapper.py index 89065f2c..80d2e267 100644 --- a/src/deepgram/core/client_wrapper.py +++ b/src/deepgram/core/client_wrapper.py @@ -28,12 +28,12 @@ def get_headers(self) -> typing.Dict[str, str]: import platform headers: typing.Dict[str, str] = { - "User-Agent": "deepgram-sdk/6.1.2", + "User-Agent": "deepgram-sdk/7.0.1", "X-Fern-Language": "Python", "X-Fern-Runtime": f"python/{platform.python_version()}", "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}", "X-Fern-SDK-Name": "deepgram-sdk", - "X-Fern-SDK-Version": "6.1.2", + "X-Fern-SDK-Version": "7.0.1", **(self.get_custom_headers() or {}), } headers["Authorization"] = f"Token {self.api_key}" diff --git a/src/deepgram/core/http_sse/_api.py b/src/deepgram/core/http_sse/_api.py index f900b3b6..b3753991 100644 --- a/src/deepgram/core/http_sse/_api.py +++ b/src/deepgram/core/http_sse/_api.py @@ -1,8 +1,9 @@ # This file was auto-generated by Fern from our API Definition. +import codecs import re from contextlib import asynccontextmanager, contextmanager -from typing import Any, AsyncGenerator, AsyncIterator, Iterator, cast +from typing import Any, AsyncGenerator, AsyncIterator, Iterator import httpx from ._decoders import SSEDecoder @@ -45,46 +46,81 @@ def _get_charset(self) -> str: def response(self) -> httpx.Response: return self._response + @staticmethod + def _normalize_sse_line_endings(buf: str) -> str: + """Normalize line endings per the SSE spec (\\r\\n → \\n, bare \\r → \\n). + + A trailing \\r is preserved because it may pair with a leading \\n in + the next chunk to form a single \\r\\n terminator. + """ + buf = buf.replace("\r\n", "\n") + if buf.endswith("\r"): + return buf[:-1].replace("\r", "\n") + "\r" + return buf.replace("\r", "\n") + def iter_sse(self) -> Iterator[ServerSentEvent]: self._check_content_type() decoder = SSEDecoder() charset = self._get_charset() + text_decoder = codecs.getincrementaldecoder(charset)(errors="replace") - buffer = "" + buf = "" for chunk in self._response.iter_bytes(): - # Decode chunk using detected charset - text_chunk = chunk.decode(charset, errors="replace") - buffer += text_chunk - - # Process complete lines - while "\n" in buffer: - line, buffer = buffer.split("\n", 1) - line = line.rstrip("\r") + buf += text_decoder.decode(chunk) + buf = self._normalize_sse_line_endings(buf) + + while "\n" in buf: + line, buf = buf.split("\n", 1) sse = decoder.decode(line) - # when we reach a "\n\n" => line = '' - # => decoder will attempt to return an SSE Event if sse is not None: yield sse - # Process any remaining data in buffer - if buffer.strip(): - line = buffer.rstrip("\r") + # Flush any remaining bytes from the incremental decoder + buf += text_decoder.decode(b"", final=True) + buf = buf.replace("\r\n", "\n").replace("\r", "\n") + + while "\n" in buf: + line, buf = buf.split("\n", 1) sse = decoder.decode(line) if sse is not None: yield sse + if buf.strip(): + sse = decoder.decode(buf) + if sse is not None: + yield sse + async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: self._check_content_type() decoder = SSEDecoder() - lines = cast(AsyncGenerator[str, None], self._response.aiter_lines()) - try: - async for line in lines: - line = line.rstrip("\n") + charset = self._get_charset() + text_decoder = codecs.getincrementaldecoder(charset)(errors="replace") + + buf = "" + async for chunk in self._response.aiter_bytes(): + buf += text_decoder.decode(chunk) + buf = self._normalize_sse_line_endings(buf) + + while "\n" in buf: + line, buf = buf.split("\n", 1) sse = decoder.decode(line) if sse is not None: yield sse - finally: - await lines.aclose() + + # Flush any remaining bytes from the incremental decoder + buf += text_decoder.decode(b"", final=True) + buf = buf.replace("\r\n", "\n").replace("\r", "\n") + + while "\n" in buf: + line, buf = buf.split("\n", 1) + sse = decoder.decode(line) + if sse is not None: + yield sse + + if buf.strip(): + sse = decoder.decode(buf) + if sse is not None: + yield sse @contextmanager diff --git a/src/deepgram/listen/v1/socket_client.py b/src/deepgram/listen/v1/socket_client.py index 5954d116..cffa82b7 100644 --- a/src/deepgram/listen/v1/socket_client.py +++ b/src/deepgram/listen/v1/socket_client.py @@ -3,7 +3,9 @@ import json import logging import typing +from json.decoder import JSONDecodeError +import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type @@ -67,7 +69,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -79,26 +81,26 @@ async def send_media(self, message: bytes) -> None: """ await self._send(message) - async def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: + async def send_finalize(self, message: ListenV1Finalize) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1Finalize. """ - await self._send_model(message or ListenV1Finalize(type="Finalize")) + await self._send_model(message) - async def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: + async def send_close_stream(self, message: ListenV1CloseStream) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1CloseStream. """ - await self._send_model(message or ListenV1CloseStream(type="CloseStream")) + await self._send_model(message) - async def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: + async def send_keep_alive(self, message: ListenV1KeepAlive) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1KeepAlive. """ - await self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) + await self._send_model(message) async def recv(self) -> V1SocketClientResponse: """ @@ -172,7 +174,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -184,26 +186,26 @@ def send_media(self, message: bytes) -> None: """ self._send(message) - def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: + def send_finalize(self, message: ListenV1Finalize) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1Finalize. """ - self._send_model(message or ListenV1Finalize(type="Finalize")) + self._send_model(message) - def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: + def send_close_stream(self, message: ListenV1CloseStream) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1CloseStream. """ - self._send_model(message or ListenV1CloseStream(type="CloseStream")) + self._send_model(message) - def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: + def send_keep_alive(self, message: ListenV1KeepAlive) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1KeepAlive. """ - self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) + self._send_model(message) def recv(self) -> V1SocketClientResponse: """ diff --git a/src/deepgram/listen/v2/client.py b/src/deepgram/listen/v2/client.py index 6b7d03b9..934deb0d 100644 --- a/src/deepgram/listen/v2/client.py +++ b/src/deepgram/listen/v2/client.py @@ -14,6 +14,7 @@ from ...core.serialization import convert_and_respect_annotation_metadata from ...core.websocket_compat import InvalidWebSocketStatus, get_status_code from ...requests.listen_v2keyterm import ListenV2KeytermParams +from ...requests.listen_v2language_hint import ListenV2LanguageHintParams from ...types.listen_v2eager_eot_threshold import ListenV2EagerEotThreshold from ...types.listen_v2encoding import ListenV2Encoding from ...types.listen_v2eot_threshold import ListenV2EotThreshold @@ -57,6 +58,7 @@ def connect( eot_threshold: typing.Optional[ListenV2EotThreshold] = None, eot_timeout_ms: typing.Optional[ListenV2EotTimeoutMs] = None, keyterm: typing.Optional[ListenV2KeytermParams] = None, + language_hint: typing.Optional[ListenV2LanguageHintParams] = None, mip_opt_out: typing.Optional[ListenV2MipOptOut] = None, tag: typing.Optional[ListenV2Tag] = None, authorization: typing.Optional[str] = None, @@ -82,6 +84,8 @@ def connect( keyterm : typing.Optional[ListenV2KeytermParams] + language_hint : typing.Optional[ListenV2LanguageHintParams] + mip_opt_out : typing.Optional[ListenV2MipOptOut] tag : typing.Optional[ListenV2Tag] @@ -116,6 +120,13 @@ def connect( annotation=ListenV2KeytermParams, direction="write", ), + "language_hint": convert_and_respect_annotation_metadata( + object_=convert_and_respect_annotation_metadata( + object_=language_hint, annotation=ListenV2LanguageHintParams, direction="write" + ), + annotation=ListenV2LanguageHintParams, + direction="write", + ), "mip_opt_out": mip_opt_out, "tag": tag, **( @@ -178,6 +189,7 @@ async def connect( eot_threshold: typing.Optional[ListenV2EotThreshold] = None, eot_timeout_ms: typing.Optional[ListenV2EotTimeoutMs] = None, keyterm: typing.Optional[ListenV2KeytermParams] = None, + language_hint: typing.Optional[ListenV2LanguageHintParams] = None, mip_opt_out: typing.Optional[ListenV2MipOptOut] = None, tag: typing.Optional[ListenV2Tag] = None, authorization: typing.Optional[str] = None, @@ -203,6 +215,8 @@ async def connect( keyterm : typing.Optional[ListenV2KeytermParams] + language_hint : typing.Optional[ListenV2LanguageHintParams] + mip_opt_out : typing.Optional[ListenV2MipOptOut] tag : typing.Optional[ListenV2Tag] @@ -237,6 +251,13 @@ async def connect( annotation=ListenV2KeytermParams, direction="write", ), + "language_hint": convert_and_respect_annotation_metadata( + object_=convert_and_respect_annotation_metadata( + object_=language_hint, annotation=ListenV2LanguageHintParams, direction="write" + ), + annotation=ListenV2LanguageHintParams, + direction="write", + ), "mip_opt_out": mip_opt_out, "tag": tag, **( diff --git a/src/deepgram/listen/v2/raw_client.py b/src/deepgram/listen/v2/raw_client.py index 53d2a13a..366feb04 100644 --- a/src/deepgram/listen/v2/raw_client.py +++ b/src/deepgram/listen/v2/raw_client.py @@ -14,6 +14,7 @@ from ...core.serialization import convert_and_respect_annotation_metadata from ...core.websocket_compat import InvalidWebSocketStatus, get_status_code from ...requests.listen_v2keyterm import ListenV2KeytermParams +from ...requests.listen_v2language_hint import ListenV2LanguageHintParams from ...types.listen_v2eager_eot_threshold import ListenV2EagerEotThreshold from ...types.listen_v2encoding import ListenV2Encoding from ...types.listen_v2eot_threshold import ListenV2EotThreshold @@ -45,6 +46,7 @@ def connect( eot_threshold: typing.Optional[ListenV2EotThreshold] = None, eot_timeout_ms: typing.Optional[ListenV2EotTimeoutMs] = None, keyterm: typing.Optional[ListenV2KeytermParams] = None, + language_hint: typing.Optional[ListenV2LanguageHintParams] = None, mip_opt_out: typing.Optional[ListenV2MipOptOut] = None, tag: typing.Optional[ListenV2Tag] = None, authorization: typing.Optional[str] = None, @@ -70,6 +72,8 @@ def connect( keyterm : typing.Optional[ListenV2KeytermParams] + language_hint : typing.Optional[ListenV2LanguageHintParams] + mip_opt_out : typing.Optional[ListenV2MipOptOut] tag : typing.Optional[ListenV2Tag] @@ -104,6 +108,13 @@ def connect( annotation=ListenV2KeytermParams, direction="write", ), + "language_hint": convert_and_respect_annotation_metadata( + object_=convert_and_respect_annotation_metadata( + object_=language_hint, annotation=ListenV2LanguageHintParams, direction="write" + ), + annotation=ListenV2LanguageHintParams, + direction="write", + ), "mip_opt_out": mip_opt_out, "tag": tag, **( @@ -155,6 +166,7 @@ async def connect( eot_threshold: typing.Optional[ListenV2EotThreshold] = None, eot_timeout_ms: typing.Optional[ListenV2EotTimeoutMs] = None, keyterm: typing.Optional[ListenV2KeytermParams] = None, + language_hint: typing.Optional[ListenV2LanguageHintParams] = None, mip_opt_out: typing.Optional[ListenV2MipOptOut] = None, tag: typing.Optional[ListenV2Tag] = None, authorization: typing.Optional[str] = None, @@ -180,6 +192,8 @@ async def connect( keyterm : typing.Optional[ListenV2KeytermParams] + language_hint : typing.Optional[ListenV2LanguageHintParams] + mip_opt_out : typing.Optional[ListenV2MipOptOut] tag : typing.Optional[ListenV2Tag] @@ -214,6 +228,13 @@ async def connect( annotation=ListenV2KeytermParams, direction="write", ), + "language_hint": convert_and_respect_annotation_metadata( + object_=convert_and_respect_annotation_metadata( + object_=language_hint, annotation=ListenV2LanguageHintParams, direction="write" + ), + annotation=ListenV2LanguageHintParams, + direction="write", + ), "mip_opt_out": mip_opt_out, "tag": tag, **( diff --git a/src/deepgram/listen/v2/socket_client.py b/src/deepgram/listen/v2/socket_client.py index d214f0f5..696c5938 100644 --- a/src/deepgram/listen/v2/socket_client.py +++ b/src/deepgram/listen/v2/socket_client.py @@ -3,12 +3,16 @@ import json import logging import typing +from json.decoder import JSONDecodeError +import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type from .types.listen_v2close_stream import ListenV2CloseStream +from .types.listen_v2configure import ListenV2Configure from .types.listen_v2configure_failure import ListenV2ConfigureFailure +from .types.listen_v2configure_success import ListenV2ConfigureSuccess from .types.listen_v2connected import ListenV2Connected from .types.listen_v2fatal_error import ListenV2FatalError from .types.listen_v2turn_info import ListenV2TurnInfo @@ -20,7 +24,7 @@ _logger = logging.getLogger(__name__) V2SocketClientResponse = typing.Union[ - ListenV2Connected, ListenV2TurnInfo, typing.Any, ListenV2ConfigureFailure, ListenV2FatalError + ListenV2Connected, ListenV2TurnInfo, ListenV2ConfigureSuccess, ListenV2ConfigureFailure, ListenV2FatalError ] @@ -67,7 +71,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -79,19 +83,19 @@ async def send_media(self, message: bytes) -> None: """ await self._send(message) - async def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: + async def send_close_stream(self, message: ListenV2CloseStream) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV2CloseStream. """ - await self._send_model(message or ListenV2CloseStream(type="CloseStream")) + await self._send_model(message) - async def send_configure(self, message: typing.Any) -> None: + async def send_configure(self, message: ListenV2Configure) -> None: """ Send a message to the websocket connection. - The message will be sent as a typing.Any. + The message will be sent as a ListenV2Configure. """ - await self._send(message) + await self._send_model(message) async def recv(self) -> V2SocketClientResponse: """ @@ -165,7 +169,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -177,19 +181,19 @@ def send_media(self, message: bytes) -> None: """ self._send(message) - def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: + def send_close_stream(self, message: ListenV2CloseStream) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV2CloseStream. """ - self._send_model(message or ListenV2CloseStream(type="CloseStream")) + self._send_model(message) - def send_configure(self, message: typing.Any) -> None: + def send_configure(self, message: ListenV2Configure) -> None: """ Send a message to the websocket connection. - The message will be sent as a typing.Any. + The message will be sent as a ListenV2Configure. """ - self._send(message) + self._send_model(message) def recv(self) -> V2SocketClientResponse: """ diff --git a/src/deepgram/manage/v1/projects/keys/client.py b/src/deepgram/manage/v1/projects/keys/client.py index 698bf841..0e089c5b 100644 --- a/src/deepgram/manage/v1/projects/keys/client.py +++ b/src/deepgram/manage/v1/projects/keys/client.py @@ -4,7 +4,7 @@ from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .....core.request_options import RequestOptions -from .....types.create_key_v1request_one import CreateKeyV1RequestOne +from .....requests.create_key_v1request import CreateKeyV1RequestParams from .....types.create_key_v1response import CreateKeyV1Response from .....types.delete_project_key_v1response import DeleteProjectKeyV1Response from .....types.get_project_key_v1response import GetProjectKeyV1Response @@ -76,7 +76,7 @@ def create( self, project_id: str, *, - request: CreateKeyV1RequestOne, + request: CreateKeyV1RequestParams, request_options: typing.Optional[RequestOptions] = None, ) -> CreateKeyV1Response: """ @@ -87,7 +87,7 @@ def create( project_id : str The unique identifier of the project - request : CreateKeyV1RequestOne + request : CreateKeyV1RequestParams request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -255,7 +255,7 @@ async def create( self, project_id: str, *, - request: CreateKeyV1RequestOne, + request: CreateKeyV1RequestParams, request_options: typing.Optional[RequestOptions] = None, ) -> CreateKeyV1Response: """ @@ -266,7 +266,7 @@ async def create( project_id : str The unique identifier of the project - request : CreateKeyV1RequestOne + request : CreateKeyV1RequestParams request_options : typing.Optional[RequestOptions] Request-specific configuration. diff --git a/src/deepgram/manage/v1/projects/keys/raw_client.py b/src/deepgram/manage/v1/projects/keys/raw_client.py index 05acd81c..2ce690c1 100644 --- a/src/deepgram/manage/v1/projects/keys/raw_client.py +++ b/src/deepgram/manage/v1/projects/keys/raw_client.py @@ -9,9 +9,10 @@ from .....core.jsonable_encoder import encode_path_param from .....core.parse_error import ParsingError from .....core.request_options import RequestOptions +from .....core.serialization import convert_and_respect_annotation_metadata from .....core.unchecked_base_model import construct_type from .....errors.bad_request_error import BadRequestError -from .....types.create_key_v1request_one import CreateKeyV1RequestOne +from .....requests.create_key_v1request import CreateKeyV1RequestParams from .....types.create_key_v1response import CreateKeyV1Response from .....types.delete_project_key_v1response import DeleteProjectKeyV1Response from .....types.get_project_key_v1response import GetProjectKeyV1Response @@ -96,7 +97,7 @@ def create( self, project_id: str, *, - request: CreateKeyV1RequestOne, + request: CreateKeyV1RequestParams, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[CreateKeyV1Response]: """ @@ -107,7 +108,7 @@ def create( project_id : str The unique identifier of the project - request : CreateKeyV1RequestOne + request : CreateKeyV1RequestParams request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -121,7 +122,9 @@ def create( f"v1/projects/{encode_path_param(project_id)}/keys", base_url=self._client_wrapper.get_environment().base, method="POST", - json=request, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateKeyV1RequestParams, direction="write" + ), headers={ "content-type": "application/json", }, @@ -348,7 +351,7 @@ async def create( self, project_id: str, *, - request: CreateKeyV1RequestOne, + request: CreateKeyV1RequestParams, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[CreateKeyV1Response]: """ @@ -359,7 +362,7 @@ async def create( project_id : str The unique identifier of the project - request : CreateKeyV1RequestOne + request : CreateKeyV1RequestParams request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -373,7 +376,9 @@ async def create( f"v1/projects/{encode_path_param(project_id)}/keys", base_url=self._client_wrapper.get_environment().base, method="POST", - json=request, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateKeyV1RequestParams, direction="write" + ), headers={ "content-type": "application/json", }, diff --git a/src/deepgram/requests/__init__.py b/src/deepgram/requests/__init__.py index a2dbf463..31a9e826 100644 --- a/src/deepgram/requests/__init__.py +++ b/src/deepgram/requests/__init__.py @@ -27,6 +27,7 @@ from .cartesia import CartesiaParams from .cartesia_speak_provider_voice import CartesiaSpeakProviderVoiceParams from .create_agent_configuration_v1response import CreateAgentConfigurationV1ResponseParams + from .create_key_v1request import CreateKeyV1RequestParams from .create_key_v1response import CreateKeyV1ResponseParams from .create_project_distribution_credentials_v1response import CreateProjectDistributionCredentialsV1ResponseParams from .create_project_distribution_credentials_v1response_distribution_credentials import ( @@ -145,6 +146,7 @@ ListenV1ResponseResultsUtterancesItemWordsItemParams, ) from .listen_v2keyterm import ListenV2KeytermParams + from .listen_v2language_hint import ListenV2LanguageHintParams from .open_ai_speak_provider import OpenAiSpeakProviderParams from .open_ai_think_provider import OpenAiThinkProviderParams from .project_request_response import ProjectRequestResponseParams @@ -234,6 +236,7 @@ "CartesiaParams": ".cartesia", "CartesiaSpeakProviderVoiceParams": ".cartesia_speak_provider_voice", "CreateAgentConfigurationV1ResponseParams": ".create_agent_configuration_v1response", + "CreateKeyV1RequestParams": ".create_key_v1request", "CreateKeyV1ResponseParams": ".create_key_v1response", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentialsParams": ".create_project_distribution_credentials_v1response_distribution_credentials", "CreateProjectDistributionCredentialsV1ResponseMemberParams": ".create_project_distribution_credentials_v1response_member", @@ -318,6 +321,7 @@ "ListenV1ResponseResultsUtterancesItemWordsItemParams": ".listen_v1response_results_utterances_item_words_item", "ListenV1ResponseResultsUtterancesParams": ".listen_v1response_results_utterances", "ListenV2KeytermParams": ".listen_v2keyterm", + "ListenV2LanguageHintParams": ".listen_v2language_hint", "OpenAiSpeakProviderParams": ".open_ai_speak_provider", "OpenAiThinkProviderParams": ".open_ai_think_provider", "ProjectRequestResponseParams": ".project_request_response", @@ -423,6 +427,7 @@ def __dir__(): "CartesiaParams", "CartesiaSpeakProviderVoiceParams", "CreateAgentConfigurationV1ResponseParams", + "CreateKeyV1RequestParams", "CreateKeyV1ResponseParams", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentialsParams", "CreateProjectDistributionCredentialsV1ResponseMemberParams", @@ -507,6 +512,7 @@ def __dir__(): "ListenV1ResponseResultsUtterancesItemWordsItemParams", "ListenV1ResponseResultsUtterancesParams", "ListenV2KeytermParams", + "ListenV2LanguageHintParams", "OpenAiSpeakProviderParams", "OpenAiThinkProviderParams", "ProjectRequestResponseParams", diff --git a/src/deepgram/requests/create_key_v1request.py b/src/deepgram/requests/create_key_v1request.py new file mode 100644 index 00000000..39196158 --- /dev/null +++ b/src/deepgram/requests/create_key_v1request.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateKeyV1RequestParams = typing.Union[typing.Any] diff --git a/src/deepgram/requests/listen_v2language_hint.py b/src/deepgram/requests/listen_v2language_hint.py new file mode 100644 index 00000000..be0e1b53 --- /dev/null +++ b/src/deepgram/requests/listen_v2language_hint.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ListenV2LanguageHintParams = typing.Union[str, typing.Sequence[str]] diff --git a/src/deepgram/speak/v1/socket_client.py b/src/deepgram/speak/v1/socket_client.py index e3c28bb5..9f1cad28 100644 --- a/src/deepgram/speak/v1/socket_client.py +++ b/src/deepgram/speak/v1/socket_client.py @@ -3,7 +3,9 @@ import json import logging import typing +from json.decoder import JSONDecodeError +import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type @@ -68,7 +70,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -80,26 +82,26 @@ async def send_text(self, message: SpeakV1Text) -> None: """ await self._send_model(message) - async def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: + async def send_flush(self, message: SpeakV1Flush) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Flush. """ - await self._send_model(message or SpeakV1Flush(type="Flush")) + await self._send_model(message) - async def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: + async def send_clear(self, message: SpeakV1Clear) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Clear. """ - await self._send_model(message or SpeakV1Clear(type="Clear")) + await self._send_model(message) - async def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: + async def send_close(self, message: SpeakV1Close) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Close. """ - await self._send_model(message or SpeakV1Close(type="Close")) + await self._send_model(message) async def recv(self) -> V1SocketClientResponse: """ @@ -173,7 +175,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except Exception as exc: + except (websockets.WebSocketException, JSONDecodeError) as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -185,26 +187,26 @@ def send_text(self, message: SpeakV1Text) -> None: """ self._send_model(message) - def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: + def send_flush(self, message: SpeakV1Flush) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Flush. """ - self._send_model(message or SpeakV1Flush(type="Flush")) + self._send_model(message) - def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: + def send_clear(self, message: SpeakV1Clear) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Clear. """ - self._send_model(message or SpeakV1Clear(type="Clear")) + self._send_model(message) - def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: + def send_close(self, message: SpeakV1Close) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Close. """ - self._send_model(message or SpeakV1Close(type="Close")) + self._send_model(message) def recv(self) -> V1SocketClientResponse: """ diff --git a/src/deepgram/types/__init__.py b/src/deepgram/types/__init__.py index 44266edb..463da29f 100644 --- a/src/deepgram/types/__init__.py +++ b/src/deepgram/types/__init__.py @@ -37,7 +37,7 @@ from .cartesia_speak_provider_model_id import CartesiaSpeakProviderModelId from .cartesia_speak_provider_voice import CartesiaSpeakProviderVoice from .create_agent_configuration_v1response import CreateAgentConfigurationV1Response - from .create_key_v1request_one import CreateKeyV1RequestOne + from .create_key_v1request import CreateKeyV1Request from .create_key_v1response import CreateKeyV1Response from .create_project_distribution_credentials_v1response import CreateProjectDistributionCredentialsV1Response from .create_project_distribution_credentials_v1response_distribution_credentials import ( @@ -194,6 +194,7 @@ from .listen_v2eot_threshold import ListenV2EotThreshold from .listen_v2eot_timeout_ms import ListenV2EotTimeoutMs from .listen_v2keyterm import ListenV2Keyterm + from .listen_v2language_hint import ListenV2LanguageHint from .listen_v2mip_opt_out import ListenV2MipOptOut from .listen_v2model import ListenV2Model from .listen_v2sample_rate import ListenV2SampleRate @@ -304,7 +305,7 @@ "CartesiaSpeakProviderModelId": ".cartesia_speak_provider_model_id", "CartesiaSpeakProviderVoice": ".cartesia_speak_provider_voice", "CreateAgentConfigurationV1Response": ".create_agent_configuration_v1response", - "CreateKeyV1RequestOne": ".create_key_v1request_one", + "CreateKeyV1Request": ".create_key_v1request", "CreateKeyV1Response": ".create_key_v1response", "CreateProjectDistributionCredentialsV1Response": ".create_project_distribution_credentials_v1response", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentials": ".create_project_distribution_credentials_v1response_distribution_credentials", @@ -429,6 +430,7 @@ "ListenV2EotThreshold": ".listen_v2eot_threshold", "ListenV2EotTimeoutMs": ".listen_v2eot_timeout_ms", "ListenV2Keyterm": ".listen_v2keyterm", + "ListenV2LanguageHint": ".listen_v2language_hint", "ListenV2MipOptOut": ".listen_v2mip_opt_out", "ListenV2Model": ".listen_v2model", "ListenV2SampleRate": ".listen_v2sample_rate", @@ -557,7 +559,7 @@ def __dir__(): "CartesiaSpeakProviderModelId", "CartesiaSpeakProviderVoice", "CreateAgentConfigurationV1Response", - "CreateKeyV1RequestOne", + "CreateKeyV1Request", "CreateKeyV1Response", "CreateProjectDistributionCredentialsV1Response", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentials", @@ -682,6 +684,7 @@ def __dir__(): "ListenV2EotThreshold", "ListenV2EotTimeoutMs", "ListenV2Keyterm", + "ListenV2LanguageHint", "ListenV2MipOptOut", "ListenV2Model", "ListenV2SampleRate", diff --git a/src/deepgram/types/create_key_v1request_one.py b/src/deepgram/types/create_key_v1request.py similarity index 63% rename from src/deepgram/types/create_key_v1request_one.py rename to src/deepgram/types/create_key_v1request.py index 0a5d546a..6e566877 100644 --- a/src/deepgram/types/create_key_v1request_one.py +++ b/src/deepgram/types/create_key_v1request.py @@ -2,4 +2,4 @@ import typing -CreateKeyV1RequestOne = typing.Any +CreateKeyV1Request = typing.Union[typing.Any] diff --git a/src/deepgram/types/listen_v2language_hint.py b/src/deepgram/types/listen_v2language_hint.py new file mode 100644 index 00000000..50773afa --- /dev/null +++ b/src/deepgram/types/listen_v2language_hint.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ListenV2LanguageHint = typing.Union[str, typing.List[str]] diff --git a/tests/wire/test_read_v1_text.py b/tests/wire/test_read_v1_text.py index 88af46fe..9d8decbd 100644 --- a/tests/wire/test_read_v1_text.py +++ b/tests/wire/test_read_v1_text.py @@ -1,7 +1,5 @@ from .conftest import get_client, verify_request_count -from deepgram import ReadV1RequestUrl - def test_read_v1_text_analyze() -> None: """Test analyze endpoint with WireMock""" @@ -20,9 +18,7 @@ def test_read_v1_text_analyze() -> None: custom_intent=["custom_intent"], custom_intent_mode="extended", language="language", - request=ReadV1RequestUrl( - url="url", - ), + request={"url": "url"}, ) verify_request_count( test_id, diff --git a/uv.lock b/uv.lock deleted file mode 100644 index 43210fc9..00000000 --- a/uv.lock +++ /dev/null @@ -1,479 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.14" - -[[package]] -name = "aiohappyeyeballs" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, -] - -[[package]] -name = "aiohttp" -version = "3.13.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/77/9a/152096d4808df8e4268befa55fba462f440f14beab85e8ad9bf990516918/aiohttp-3.13.5.tar.gz", hash = "sha256:9d98cc980ecc96be6eb4c1994ce35d28d8b1f5e5208a23b421187d1209dbb7d1", size = 7858271, upload-time = "2026-03-31T22:01:03.343Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/ce/46572759afc859e867a5bc8ec3487315869013f59281ce61764f76d879de/aiohttp-3.13.5-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:eb4639f32fd4a9904ab8fb45bf3383ba71137f3d9d4ba25b3b3f3109977c5b8c", size = 745721, upload-time = "2026-03-31T21:58:50.229Z" }, - { url = "https://files.pythonhosted.org/packages/13/fe/8a2efd7626dbe6049b2ef8ace18ffda8a4dfcbe1bcff3ac30c0c7575c20b/aiohttp-3.13.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:7e5dc4311bd5ac493886c63cbf76ab579dbe4641268e7c74e48e774c74b6f2be", size = 497663, upload-time = "2026-03-31T21:58:52.232Z" }, - { url = "https://files.pythonhosted.org/packages/9b/91/cc8cc78a111826c54743d88651e1687008133c37e5ee615fee9b57990fac/aiohttp-3.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:756c3c304d394977519824449600adaf2be0ccee76d206ee339c5e76b70ded25", size = 499094, upload-time = "2026-03-31T21:58:54.566Z" }, - { url = "https://files.pythonhosted.org/packages/0a/33/a8362cb15cf16a3af7e86ed11962d5cd7d59b449202dc576cdc731310bde/aiohttp-3.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecc26751323224cf8186efcf7fbcbc30f4e1d8c7970659daf25ad995e4032a56", size = 1726701, upload-time = "2026-03-31T21:58:56.864Z" }, - { url = "https://files.pythonhosted.org/packages/45/0c/c091ac5c3a17114bd76cbf85d674650969ddf93387876cf67f754204bd77/aiohttp-3.13.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10a75acfcf794edf9d8db50e5a7ec5fc818b2a8d3f591ce93bc7b1210df016d2", size = 1683360, upload-time = "2026-03-31T21:58:59.072Z" }, - { url = "https://files.pythonhosted.org/packages/23/73/bcee1c2b79bc275e964d1446c55c54441a461938e70267c86afaae6fba27/aiohttp-3.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f7a18f258d124cd678c5fe072fe4432a4d5232b0657fca7c1847f599233c83a", size = 1773023, upload-time = "2026-03-31T21:59:01.776Z" }, - { url = "https://files.pythonhosted.org/packages/c7/ef/720e639df03004fee2d869f771799d8c23046dec47d5b81e396c7cda583a/aiohttp-3.13.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df6104c009713d3a89621096f3e3e88cc323fd269dbd7c20afe18535094320be", size = 1853795, upload-time = "2026-03-31T21:59:04.568Z" }, - { url = "https://files.pythonhosted.org/packages/bd/c9/989f4034fb46841208de7aeeac2c6d8300745ab4f28c42f629ba77c2d916/aiohttp-3.13.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:241a94f7de7c0c3b616627aaad530fe2cb620084a8b144d3be7b6ecfe95bae3b", size = 1730405, upload-time = "2026-03-31T21:59:07.221Z" }, - { url = "https://files.pythonhosted.org/packages/ce/75/ee1fd286ca7dc599d824b5651dad7b3be7ff8d9a7e7b3fe9820d9180f7db/aiohttp-3.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c974fb66180e58709b6fc402846f13791240d180b74de81d23913abe48e96d94", size = 1558082, upload-time = "2026-03-31T21:59:09.484Z" }, - { url = "https://files.pythonhosted.org/packages/c3/20/1e9e6650dfc436340116b7aa89ff8cb2bbdf0abc11dfaceaad8f74273a10/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6e27ea05d184afac78aabbac667450c75e54e35f62238d44463131bd3f96753d", size = 1692346, upload-time = "2026-03-31T21:59:12.068Z" }, - { url = "https://files.pythonhosted.org/packages/d8/40/8ebc6658d48ea630ac7903912fe0dd4e262f0e16825aa4c833c56c9f1f56/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a79a6d399cef33a11b6f004c67bb07741d91f2be01b8d712d52c75711b1e07c7", size = 1698891, upload-time = "2026-03-31T21:59:14.552Z" }, - { url = "https://files.pythonhosted.org/packages/d8/78/ea0ae5ec8ba7a5c10bdd6e318f1ba5e76fcde17db8275188772afc7917a4/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c632ce9c0b534fbe25b52c974515ed674937c5b99f549a92127c85f771a78772", size = 1742113, upload-time = "2026-03-31T21:59:17.068Z" }, - { url = "https://files.pythonhosted.org/packages/8a/66/9d308ed71e3f2491be1acb8769d96c6f0c47d92099f3bc9119cada27b357/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fceedde51fbd67ee2bcc8c0b33d0126cc8b51ef3bbde2f86662bd6d5a6f10ec5", size = 1553088, upload-time = "2026-03-31T21:59:19.541Z" }, - { url = "https://files.pythonhosted.org/packages/da/a6/6cc25ed8dfc6e00c90f5c6d126a98e2cf28957ad06fa1036bd34b6f24a2c/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f92995dfec9420bb69ae629abf422e516923ba79ba4403bc750d94fb4a6c68c1", size = 1757976, upload-time = "2026-03-31T21:59:22.311Z" }, - { url = "https://files.pythonhosted.org/packages/c1/2b/cce5b0ffe0de99c83e5e36d8f828e4161e415660a9f3e58339d07cce3006/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20ae0ff08b1f2c8788d6fb85afcb798654ae6ba0b747575f8562de738078457b", size = 1712444, upload-time = "2026-03-31T21:59:24.635Z" }, - { url = "https://files.pythonhosted.org/packages/6c/cf/9e1795b4160c58d29421eafd1a69c6ce351e2f7c8d3c6b7e4ca44aea1a5b/aiohttp-3.13.5-cp314-cp314-win32.whl", hash = "sha256:b20df693de16f42b2472a9c485e1c948ee55524786a0a34345511afdd22246f3", size = 438128, upload-time = "2026-03-31T21:59:27.291Z" }, - { url = "https://files.pythonhosted.org/packages/22/4d/eaedff67fc805aeba4ba746aec891b4b24cebb1a7d078084b6300f79d063/aiohttp-3.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:f85c6f327bf0b8c29da7d93b1cabb6363fb5e4e160a32fa241ed2dce21b73162", size = 464029, upload-time = "2026-03-31T21:59:29.429Z" }, - { url = "https://files.pythonhosted.org/packages/79/11/c27d9332ee20d68dd164dc12a6ecdef2e2e35ecc97ed6cf0d2442844624b/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:1efb06900858bb618ff5cee184ae2de5828896c448403d51fb633f09e109be0a", size = 778758, upload-time = "2026-03-31T21:59:31.547Z" }, - { url = "https://files.pythonhosted.org/packages/04/fb/377aead2e0a3ba5f09b7624f702a964bdf4f08b5b6728a9799830c80041e/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fee86b7c4bd29bdaf0d53d14739b08a106fdda809ca5fe032a15f52fae5fe254", size = 512883, upload-time = "2026-03-31T21:59:34.098Z" }, - { url = "https://files.pythonhosted.org/packages/bb/a6/aa109a33671f7a5d3bd78b46da9d852797c5e665bfda7d6b373f56bff2ec/aiohttp-3.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:20058e23909b9e65f9da62b396b77dfa95965cbe840f8def6e572538b1d32e36", size = 516668, upload-time = "2026-03-31T21:59:36.497Z" }, - { url = "https://files.pythonhosted.org/packages/79/b3/ca078f9f2fa9563c36fb8ef89053ea2bb146d6f792c5104574d49d8acb63/aiohttp-3.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cf20a8d6868cb15a73cab329ffc07291ba8c22b1b88176026106ae39aa6df0f", size = 1883461, upload-time = "2026-03-31T21:59:38.723Z" }, - { url = "https://files.pythonhosted.org/packages/b7/e3/a7ad633ca1ca497b852233a3cce6906a56c3225fb6d9217b5e5e60b7419d/aiohttp-3.13.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:330f5da04c987f1d5bdb8ae189137c77139f36bd1cb23779ca1a354a4b027800", size = 1747661, upload-time = "2026-03-31T21:59:41.187Z" }, - { url = "https://files.pythonhosted.org/packages/33/b9/cd6fe579bed34a906d3d783fe60f2fa297ef55b27bb4538438ee49d4dc41/aiohttp-3.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f1cbf0c7926d315c3c26c2da41fd2b5d2fe01ac0e157b78caefc51a782196cf", size = 1863800, upload-time = "2026-03-31T21:59:43.84Z" }, - { url = "https://files.pythonhosted.org/packages/c0/3f/2c1e2f5144cefa889c8afd5cf431994c32f3b29da9961698ff4e3811b79a/aiohttp-3.13.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:53fc049ed6390d05423ba33103ded7281fe897cf97878f369a527070bd95795b", size = 1958382, upload-time = "2026-03-31T21:59:46.187Z" }, - { url = "https://files.pythonhosted.org/packages/66/1d/f31ec3f1013723b3babe3609e7f119c2c2fb6ef33da90061a705ef3e1bc8/aiohttp-3.13.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:898703aa2667e3c5ca4c54ca36cd73f58b7a38ef87a5606414799ebce4d3fd3a", size = 1803724, upload-time = "2026-03-31T21:59:48.656Z" }, - { url = "https://files.pythonhosted.org/packages/0e/b4/57712dfc6f1542f067daa81eb61da282fab3e6f1966fca25db06c4fc62d5/aiohttp-3.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0494a01ca9584eea1e5fbd6d748e61ecff218c51b576ee1999c23db7066417d8", size = 1640027, upload-time = "2026-03-31T21:59:51.284Z" }, - { url = "https://files.pythonhosted.org/packages/25/3c/734c878fb43ec083d8e31bf029daae1beafeae582d1b35da234739e82ee7/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6cf81fe010b8c17b09495cbd15c1d35afbc8fb405c0c9cf4738e5ae3af1d65be", size = 1806644, upload-time = "2026-03-31T21:59:53.753Z" }, - { url = "https://files.pythonhosted.org/packages/20/a5/f671e5cbec1c21d044ff3078223f949748f3a7f86b14e34a365d74a5d21f/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:c564dd5f09ddc9d8f2c2d0a301cd30a79a2cc1b46dd1a73bef8f0038863d016b", size = 1791630, upload-time = "2026-03-31T21:59:56.239Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/fb8d0ad63a0b8a99be97deac8c04dacf0785721c158bdf23d679a87aa99e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2994be9f6e51046c4f864598fd9abeb4fba6e88f0b2152422c9666dcd4aea9c6", size = 1809403, upload-time = "2026-03-31T21:59:59.103Z" }, - { url = "https://files.pythonhosted.org/packages/59/0c/bfed7f30662fcf12206481c2aac57dedee43fe1c49275e85b3a1e1742294/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:157826e2fa245d2ef46c83ea8a5faf77ca19355d278d425c29fda0beb3318037", size = 1634924, upload-time = "2026-03-31T22:00:02.116Z" }, - { url = "https://files.pythonhosted.org/packages/17/d6/fd518d668a09fd5a3319ae5e984d4d80b9a4b3df4e21c52f02251ef5a32e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a8aca50daa9493e9e13c0f566201a9006f080e7c50e5e90d0b06f53146a54500", size = 1836119, upload-time = "2026-03-31T22:00:04.756Z" }, - { url = "https://files.pythonhosted.org/packages/78/b7/15fb7a9d52e112a25b621c67b69c167805cb1f2ab8f1708a5c490d1b52fe/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3b13560160d07e047a93f23aaa30718606493036253d5430887514715b67c9d9", size = 1772072, upload-time = "2026-03-31T22:00:07.494Z" }, - { url = "https://files.pythonhosted.org/packages/7e/df/57ba7f0c4a553fc2bd8b6321df236870ec6fd64a2a473a8a13d4f733214e/aiohttp-3.13.5-cp314-cp314t-win32.whl", hash = "sha256:9a0f4474b6ea6818b41f82172d799e4b3d29e22c2c520ce4357856fced9af2f8", size = 471819, upload-time = "2026-03-31T22:00:10.277Z" }, - { url = "https://files.pythonhosted.org/packages/62/29/2f8418269e46454a26171bfdd6a055d74febf32234e474930f2f60a17145/aiohttp-3.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:18a2f6c1182c51baa1d28d68fea51513cb2a76612f038853c0ad3c145423d3d9", size = 505441, upload-time = "2026-03-31T22:00:12.791Z" }, -] - -[[package]] -name = "aiosignal" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, -] - -[[package]] -name = "anyio" -version = "4.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, -] - -[[package]] -name = "attrs" -version = "26.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, -] - -[[package]] -name = "certifi" -version = "2026.4.22" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, -] - -[[package]] -name = "deepgram-sdk" -source = { editable = "." } -dependencies = [ - { name = "httpx" }, - { name = "pydantic" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "websockets" }, -] - -[package.optional-dependencies] -aiohttp = [ - { name = "aiohttp" }, - { name = "httpx-aiohttp" }, -] - -[package.metadata] -requires-dist = [ - { name = "aiohttp", marker = "python_full_version >= '3.9' and extra == 'aiohttp'", specifier = ">=3.13.4,<4" }, - { name = "httpx", specifier = ">=0.21.2" }, - { name = "httpx-aiohttp", marker = "python_full_version >= '3.9' and extra == 'aiohttp'", specifier = "==0.1.8" }, - { name = "pydantic", specifier = ">=1.9.2" }, - { name = "pydantic-core", specifier = ">=2.18.2,<2.44.0" }, - { name = "typing-extensions", specifier = ">=4.0.0" }, - { name = "websockets", specifier = ">=12.0" }, -] -provides-extras = ["aiohttp"] - -[[package]] -name = "frozenlist" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, - { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, - { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, - { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, - { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, - { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, - { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, - { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, - { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, - { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, - { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, - { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, - { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, - { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, - { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, - { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, - { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, - { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, - { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, - { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, - { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, - { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, - { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, - { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, - { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, -] - -[[package]] -name = "httpx-aiohttp" -version = "0.1.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "httpx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/37/19/ae2d2bf1f57fdd23c8ad83675599fb5c407fa13bc20e90f00cffa4dea3aa/httpx_aiohttp-0.1.8.tar.gz", hash = "sha256:756c5e74cdb568c3248ba63fe82bfe8bbe64b928728720f7eaac64b3cf46f308", size = 25401, upload-time = "2025-07-04T10:40:32.329Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/7a/514c484b88cc4ebbcd2e27e92b86019c0c5bb920582f5fbb10b7e6c78574/httpx_aiohttp-0.1.8-py3-none-any.whl", hash = "sha256:b7bd958d1331f3759a38a0ba22ad29832cb63ca69498c17735228055bf78fa7e", size = 6180, upload-time = "2025-07-04T10:40:31.522Z" }, -] - -[[package]] -name = "idna" -version = "3.13" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" }, -] - -[[package]] -name = "multidict" -version = "6.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/91/cc/db74228a8be41884a567e88a62fd589a913708fcf180d029898c17a9a371/multidict-6.7.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8f333ec9c5eb1b7105e3b84b53141e66ca05a19a605368c55450b6ba208cb9ee", size = 75190, upload-time = "2026-01-26T02:45:10.651Z" }, - { url = "https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2", size = 44486, upload-time = "2026-01-26T02:45:11.938Z" }, - { url = "https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1", size = 43219, upload-time = "2026-01-26T02:45:14.346Z" }, - { url = "https://files.pythonhosted.org/packages/24/bb/2c0c2287963f4259c85e8bcbba9182ced8d7fca65c780c38e99e61629d11/multidict-6.7.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1e3a8bb24342a8201d178c3b4984c26ba81a577c80d4d525727427460a50c22d", size = 245132, upload-time = "2026-01-26T02:45:15.712Z" }, - { url = "https://files.pythonhosted.org/packages/a7/f9/44d4b3064c65079d2467888794dea218d1601898ac50222ab8a9a8094460/multidict-6.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97231140a50f5d447d3164f994b86a0bed7cd016e2682f8650d6a9158e14fd31", size = 252420, upload-time = "2026-01-26T02:45:17.293Z" }, - { url = "https://files.pythonhosted.org/packages/8b/13/78f7275e73fa17b24c9a51b0bd9d73ba64bb32d0ed51b02a746eb876abe7/multidict-6.7.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b10359683bd8806a200fd2909e7c8ca3a7b24ec1d8132e483d58e791d881048", size = 233510, upload-time = "2026-01-26T02:45:19.356Z" }, - { url = "https://files.pythonhosted.org/packages/4b/25/8167187f62ae3cbd52da7893f58cb036b47ea3fb67138787c76800158982/multidict-6.7.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:283ddac99f7ac25a4acadbf004cb5ae34480bbeb063520f70ce397b281859362", size = 264094, upload-time = "2026-01-26T02:45:20.834Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e7/69a3a83b7b030cf283fb06ce074a05a02322359783424d7edf0f15fe5022/multidict-6.7.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:538cec1e18c067d0e6103aa9a74f9e832904c957adc260e61cd9d8cf0c3b3d37", size = 260786, upload-time = "2026-01-26T02:45:22.818Z" }, - { url = "https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709", size = 248483, upload-time = "2026-01-26T02:45:24.368Z" }, - { url = "https://files.pythonhosted.org/packages/48/5a/d5a99e3acbca0e29c5d9cba8f92ceb15dce78bab963b308ae692981e3a5d/multidict-6.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa263a02f4f2dd2d11a7b1bb4362aa7cb1049f84a9235d31adf63f30143469a0", size = 248403, upload-time = "2026-01-26T02:45:25.982Z" }, - { url = "https://files.pythonhosted.org/packages/35/48/e58cd31f6c7d5102f2a4bf89f96b9cf7e00b6c6f3d04ecc44417c00a5a3c/multidict-6.7.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2e1425e2f99ec5bd36c15a01b690a1a2456209c5deed58f95469ffb46039ccbb", size = 240315, upload-time = "2026-01-26T02:45:27.487Z" }, - { url = "https://files.pythonhosted.org/packages/94/33/1cd210229559cb90b6786c30676bb0c58249ff42f942765f88793b41fdce/multidict-6.7.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:497394b3239fc6f0e13a78a3e1b61296e72bf1c5f94b4c4eb80b265c37a131cd", size = 245528, upload-time = "2026-01-26T02:45:28.991Z" }, - { url = "https://files.pythonhosted.org/packages/64/f2/6e1107d226278c876c783056b7db43d800bb64c6131cec9c8dfb6903698e/multidict-6.7.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:233b398c29d3f1b9676b4b6f75c518a06fcb2ea0b925119fb2c1bc35c05e1601", size = 258784, upload-time = "2026-01-26T02:45:30.503Z" }, - { url = "https://files.pythonhosted.org/packages/4d/c1/11f664f14d525e4a1b5327a82d4de61a1db604ab34c6603bb3c2cc63ad34/multidict-6.7.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:93b1818e4a6e0930454f0f2af7dfce69307ca03cdcfb3739bf4d91241967b6c1", size = 251980, upload-time = "2026-01-26T02:45:32.603Z" }, - { url = "https://files.pythonhosted.org/packages/e1/9f/75a9ac888121d0c5bbd4ecf4eead45668b1766f6baabfb3b7f66a410e231/multidict-6.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f33dc2a3abe9249ea5d8360f969ec7f4142e7ac45ee7014d8f8d5acddf178b7b", size = 243602, upload-time = "2026-01-26T02:45:34.043Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e7/50bf7b004cc8525d80dbbbedfdc7aed3e4c323810890be4413e589074032/multidict-6.7.1-cp314-cp314-win32.whl", hash = "sha256:3ab8b9d8b75aef9df299595d5388b14530839f6422333357af1339443cff777d", size = 40930, upload-time = "2026-01-26T02:45:36.278Z" }, - { url = "https://files.pythonhosted.org/packages/e0/bf/52f25716bbe93745595800f36fb17b73711f14da59ed0bb2eba141bc9f0f/multidict-6.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:5e01429a929600e7dab7b166062d9bb54a5eed752384c7384c968c2afab8f50f", size = 45074, upload-time = "2026-01-26T02:45:37.546Z" }, - { url = "https://files.pythonhosted.org/packages/97/ab/22803b03285fa3a525f48217963da3a65ae40f6a1b6f6cf2768879e208f9/multidict-6.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:4885cb0e817aef5d00a2e8451d4665c1808378dc27c2705f1bf4ef8505c0d2e5", size = 42471, upload-time = "2026-01-26T02:45:38.889Z" }, - { url = "https://files.pythonhosted.org/packages/e0/6d/f9293baa6146ba9507e360ea0292b6422b016907c393e2f63fc40ab7b7b5/multidict-6.7.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0458c978acd8e6ea53c81eefaddbbee9c6c5e591f41b3f5e8e194780fe026581", size = 82401, upload-time = "2026-01-26T02:45:40.254Z" }, - { url = "https://files.pythonhosted.org/packages/7a/68/53b5494738d83558d87c3c71a486504d8373421c3e0dbb6d0db48ad42ee0/multidict-6.7.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c0abd12629b0af3cf590982c0b413b1e7395cd4ec026f30986818ab95bfaa94a", size = 48143, upload-time = "2026-01-26T02:45:41.635Z" }, - { url = "https://files.pythonhosted.org/packages/37/e8/5284c53310dcdc99ce5d66563f6e5773531a9b9fe9ec7a615e9bc306b05f/multidict-6.7.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:14525a5f61d7d0c94b368a42cff4c9a4e7ba2d52e2672a7b23d84dc86fb02b0c", size = 46507, upload-time = "2026-01-26T02:45:42.99Z" }, - { url = "https://files.pythonhosted.org/packages/e4/fc/6800d0e5b3875568b4083ecf5f310dcf91d86d52573160834fb4bfcf5e4f/multidict-6.7.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17307b22c217b4cf05033dabefe68255a534d637c6c9b0cc8382718f87be4262", size = 239358, upload-time = "2026-01-26T02:45:44.376Z" }, - { url = "https://files.pythonhosted.org/packages/41/75/4ad0973179361cdf3a113905e6e088173198349131be2b390f9fa4da5fc6/multidict-6.7.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a7e590ff876a3eaf1c02a4dfe0724b6e69a9e9de6d8f556816f29c496046e59", size = 246884, upload-time = "2026-01-26T02:45:47.167Z" }, - { url = "https://files.pythonhosted.org/packages/c3/9c/095bb28b5da139bd41fb9a5d5caff412584f377914bd8787c2aa98717130/multidict-6.7.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5fa6a95dfee63893d80a34758cd0e0c118a30b8dcb46372bf75106c591b77889", size = 225878, upload-time = "2026-01-26T02:45:48.698Z" }, - { url = "https://files.pythonhosted.org/packages/07/d0/c0a72000243756e8f5a277b6b514fa005f2c73d481b7d9e47cd4568aa2e4/multidict-6.7.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a0543217a6a017692aa6ae5cc39adb75e587af0f3a82288b1492eb73dd6cc2a4", size = 253542, upload-time = "2026-01-26T02:45:50.164Z" }, - { url = "https://files.pythonhosted.org/packages/c0/6b/f69da15289e384ecf2a68837ec8b5ad8c33e973aa18b266f50fe55f24b8c/multidict-6.7.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f99fe611c312b3c1c0ace793f92464d8cd263cc3b26b5721950d977b006b6c4d", size = 252403, upload-time = "2026-01-26T02:45:51.779Z" }, - { url = "https://files.pythonhosted.org/packages/a2/76/b9669547afa5a1a25cd93eaca91c0da1c095b06b6d2d8ec25b713588d3a1/multidict-6.7.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9004d8386d133b7e6135679424c91b0b854d2d164af6ea3f289f8f2761064609", size = 244889, upload-time = "2026-01-26T02:45:53.27Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a9/a50d2669e506dad33cfc45b5d574a205587b7b8a5f426f2fbb2e90882588/multidict-6.7.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e628ef0e6859ffd8273c69412a2465c4be4a9517d07261b33334b5ec6f3c7489", size = 241982, upload-time = "2026-01-26T02:45:54.919Z" }, - { url = "https://files.pythonhosted.org/packages/c5/bb/1609558ad8b456b4827d3c5a5b775c93b87878fd3117ed3db3423dfbce1b/multidict-6.7.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:841189848ba629c3552035a6a7f5bf3b02eb304e9fea7492ca220a8eda6b0e5c", size = 232415, upload-time = "2026-01-26T02:45:56.981Z" }, - { url = "https://files.pythonhosted.org/packages/d8/59/6f61039d2aa9261871e03ab9dc058a550d240f25859b05b67fd70f80d4b3/multidict-6.7.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce1bbd7d780bb5a0da032e095c951f7014d6b0a205f8318308140f1a6aba159e", size = 240337, upload-time = "2026-01-26T02:45:58.698Z" }, - { url = "https://files.pythonhosted.org/packages/a1/29/fdc6a43c203890dc2ae9249971ecd0c41deaedfe00d25cb6564b2edd99eb/multidict-6.7.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b26684587228afed0d50cf804cc71062cc9c1cdf55051c4c6345d372947b268c", size = 248788, upload-time = "2026-01-26T02:46:00.862Z" }, - { url = "https://files.pythonhosted.org/packages/a9/14/a153a06101323e4cf086ecee3faadba52ff71633d471f9685c42e3736163/multidict-6.7.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9f9af11306994335398293f9958071019e3ab95e9a707dc1383a35613f6abcb9", size = 242842, upload-time = "2026-01-26T02:46:02.824Z" }, - { url = "https://files.pythonhosted.org/packages/41/5f/604ae839e64a4a6efc80db94465348d3b328ee955e37acb24badbcd24d83/multidict-6.7.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b4938326284c4f1224178a560987b6cf8b4d38458b113d9b8c1db1a836e640a2", size = 240237, upload-time = "2026-01-26T02:46:05.898Z" }, - { url = "https://files.pythonhosted.org/packages/5f/60/c3a5187bf66f6fb546ff4ab8fb5a077cbdd832d7b1908d4365c7f74a1917/multidict-6.7.1-cp314-cp314t-win32.whl", hash = "sha256:98655c737850c064a65e006a3df7c997cd3b220be4ec8fe26215760b9697d4d7", size = 48008, upload-time = "2026-01-26T02:46:07.468Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f7/addf1087b860ac60e6f382240f64fb99f8bfb532bb06f7c542b83c29ca61/multidict-6.7.1-cp314-cp314t-win_amd64.whl", hash = "sha256:497bde6223c212ba11d462853cfa4f0ae6ef97465033e7dc9940cdb3ab5b48e5", size = 53542, upload-time = "2026-01-26T02:46:08.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/81/4629d0aa32302ef7b2ec65c75a728cc5ff4fa410c50096174c1632e70b3e/multidict-6.7.1-cp314-cp314t-win_arm64.whl", hash = "sha256:2bbd113e0d4af5db41d5ebfe9ccaff89de2120578164f86a5d17d5a576d1e5b2", size = 44719, upload-time = "2026-01-26T02:46:11.146Z" }, - { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, -] - -[[package]] -name = "propcache" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, - { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, - { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, - { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, - { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, - { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, - { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, - { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, - { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, - { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, - { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, - { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, - { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, - { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, - { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, - { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, - { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, - { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, - { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, - { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, -] - -[[package]] -name = "websockets" -version = "16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" }, - { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" }, - { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" }, - { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" }, - { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" }, - { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" }, - { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" }, - { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" }, - { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" }, - { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" }, - { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" }, - { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" }, - { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" }, - { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, -] - -[[package]] -name = "yarl" -version = "1.23.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, -] From d9a20f937338a8ea68b9c1a6791180c5f0a2f2bc Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 29 Apr 2026 14:18:55 +0100 Subject: [PATCH 4/6] chore: re-apply manual patches after regen --- .fernignore | 8 +- src/deepgram/agent/v1/socket_client.py | 40 ++- src/deepgram/agent/v1/socket_client.py.bak | 361 -------------------- src/deepgram/listen/v1/socket_client.py | 30 +- src/deepgram/listen/v1/socket_client.py.bak | 234 ------------- src/deepgram/listen/v2/socket_client.py | 30 +- src/deepgram/listen/v2/socket_client.py.bak | 220 ------------ src/deepgram/speak/v1/socket_client.py | 30 +- src/deepgram/speak/v1/socket_client.py.bak | 235 ------------- tests/custom/test_agent_history.py | 6 +- 10 files changed, 78 insertions(+), 1116 deletions(-) delete mode 100644 src/deepgram/agent/v1/socket_client.py.bak delete mode 100644 src/deepgram/listen/v1/socket_client.py.bak delete mode 100644 src/deepgram/listen/v2/socket_client.py.bak delete mode 100644 src/deepgram/speak/v1/socket_client.py.bak diff --git a/.fernignore b/.fernignore index 5cdd1ea6..642889b3 100644 --- a/.fernignore +++ b/.fernignore @@ -12,10 +12,10 @@ src/deepgram/client.py # - listen/v2 send_configure: typing.Any / raw _send shim (generator's ListenV2Configure model # and ListenV2ConfigureSuccess not used) # [temporarily frozen — manual patches listed above] -src/deepgram/agent/v1/socket_client.py.bak -src/deepgram/listen/v1/socket_client.py.bak -src/deepgram/listen/v2/socket_client.py.bak -src/deepgram/speak/v1/socket_client.py.bak +src/deepgram/agent/v1/socket_client.py +src/deepgram/listen/v1/socket_client.py +src/deepgram/listen/v2/socket_client.py +src/deepgram/speak/v1/socket_client.py # Hand-written custom tests tests/custom/test_agent_history.py diff --git a/src/deepgram/agent/v1/socket_client.py b/src/deepgram/agent/v1/socket_client.py index b75080a7..17c3d0d2 100644 --- a/src/deepgram/agent/v1/socket_client.py +++ b/src/deepgram/agent/v1/socket_client.py @@ -3,9 +3,7 @@ import json import logging import typing -from json.decoder import JSONDecodeError -import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type @@ -40,6 +38,28 @@ from websockets import WebSocketClientProtocol # type: ignore _logger = logging.getLogger(__name__) + + +def _sanitize_numeric_types(obj: typing.Any) -> typing.Any: + """ + Recursively convert float values that are whole numbers to int. + + Workaround for Fern-generated models that type integer API fields + (like sample_rate) as float, causing JSON serialization to produce + values like 44100.0 instead of 44100. The Deepgram API rejects + float representations of integer fields. + + See: https://github.com/deepgram/internal-api-specs/issues/205 + """ + if isinstance(obj, dict): + return {k: _sanitize_numeric_types(v) for k, v in obj.items()} + elif isinstance(obj, list): + return [_sanitize_numeric_types(item) for item in obj] + elif isinstance(obj, float) and obj.is_integer(): + return int(obj) + return obj + + V1SocketClientResponse = typing.Union[ AgentV1ReceiveFunctionCallResponse, AgentV1PromptUpdated, @@ -104,7 +124,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -144,12 +164,12 @@ async def send_function_call_response(self, message: AgentV1SendFunctionCallResp """ await self._send_model(message) - async def send_keep_alive(self, message: AgentV1KeepAlive) -> None: + async def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a AgentV1KeepAlive. """ - await self._send_model(message) + await self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) async def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: """ @@ -198,7 +218,7 @@ async def _send_model(self, data: typing.Any) -> None: """ Send a Pydantic model to the websocket connection. """ - await self._send(data.dict()) + await self._send(_sanitize_numeric_types(data.dict())) class V1SocketClient(EventEmitterMixin): @@ -244,7 +264,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -284,12 +304,12 @@ def send_function_call_response(self, message: AgentV1SendFunctionCallResponse) """ self._send_model(message) - def send_keep_alive(self, message: AgentV1KeepAlive) -> None: + def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a AgentV1KeepAlive. """ - self._send_model(message) + self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: """ @@ -338,4 +358,4 @@ def _send_model(self, data: typing.Any) -> None: """ Send a Pydantic model to the websocket connection. """ - self._send(data.dict()) + self._send(_sanitize_numeric_types(data.dict())) diff --git a/src/deepgram/agent/v1/socket_client.py.bak b/src/deepgram/agent/v1/socket_client.py.bak deleted file mode 100644 index 17c3d0d2..00000000 --- a/src/deepgram/agent/v1/socket_client.py.bak +++ /dev/null @@ -1,361 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import json -import logging -import typing - -import websockets.sync.connection as websockets_sync_connection -from ...core.events import EventEmitterMixin, EventType -from ...core.unchecked_base_model import construct_type -from .types.agent_v1agent_audio_done import AgentV1AgentAudioDone -from .types.agent_v1agent_started_speaking import AgentV1AgentStartedSpeaking -from .types.agent_v1agent_thinking import AgentV1AgentThinking -from .types.agent_v1conversation_text import AgentV1ConversationText -from .types.agent_v1error import AgentV1Error -from .types.agent_v1function_call_request import AgentV1FunctionCallRequest -from .types.agent_v1history import AgentV1History -from .types.agent_v1inject_agent_message import AgentV1InjectAgentMessage -from .types.agent_v1inject_user_message import AgentV1InjectUserMessage -from .types.agent_v1injection_refused import AgentV1InjectionRefused -from .types.agent_v1keep_alive import AgentV1KeepAlive -from .types.agent_v1prompt_updated import AgentV1PromptUpdated -from .types.agent_v1receive_function_call_response import AgentV1ReceiveFunctionCallResponse -from .types.agent_v1send_function_call_response import AgentV1SendFunctionCallResponse -from .types.agent_v1settings import AgentV1Settings -from .types.agent_v1settings_applied import AgentV1SettingsApplied -from .types.agent_v1speak_updated import AgentV1SpeakUpdated -from .types.agent_v1think_updated import AgentV1ThinkUpdated -from .types.agent_v1update_prompt import AgentV1UpdatePrompt -from .types.agent_v1update_speak import AgentV1UpdateSpeak -from .types.agent_v1update_think import AgentV1UpdateThink -from .types.agent_v1user_started_speaking import AgentV1UserStartedSpeaking -from .types.agent_v1warning import AgentV1Warning -from .types.agent_v1welcome import AgentV1Welcome - -try: - from websockets.legacy.client import WebSocketClientProtocol # type: ignore -except ImportError: - from websockets import WebSocketClientProtocol # type: ignore - -_logger = logging.getLogger(__name__) - - -def _sanitize_numeric_types(obj: typing.Any) -> typing.Any: - """ - Recursively convert float values that are whole numbers to int. - - Workaround for Fern-generated models that type integer API fields - (like sample_rate) as float, causing JSON serialization to produce - values like 44100.0 instead of 44100. The Deepgram API rejects - float representations of integer fields. - - See: https://github.com/deepgram/internal-api-specs/issues/205 - """ - if isinstance(obj, dict): - return {k: _sanitize_numeric_types(v) for k, v in obj.items()} - elif isinstance(obj, list): - return [_sanitize_numeric_types(item) for item in obj] - elif isinstance(obj, float) and obj.is_integer(): - return int(obj) - return obj - - -V1SocketClientResponse = typing.Union[ - AgentV1ReceiveFunctionCallResponse, - AgentV1PromptUpdated, - AgentV1SpeakUpdated, - AgentV1ThinkUpdated, - AgentV1InjectionRefused, - AgentV1Welcome, - AgentV1SettingsApplied, - AgentV1ConversationText, - AgentV1UserStartedSpeaking, - AgentV1AgentThinking, - AgentV1FunctionCallRequest, - AgentV1AgentStartedSpeaking, - AgentV1AgentAudioDone, - AgentV1Error, - AgentV1Warning, - AgentV1History, - bytes, -] - - -class AsyncV1SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: WebSocketClientProtocol): - super().__init__() - self._websocket = websocket - - async def __aiter__(self): - async for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - async def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - await self._emit_async(EventType.OPEN, None) - try: - async for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: - await self._emit_async(EventType.ERROR, exc) - finally: - await self._emit_async(EventType.CLOSE, None) - - async def send_settings(self, message: AgentV1Settings) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1Settings. - """ - await self._send_model(message) - - async def send_update_speak(self, message: AgentV1UpdateSpeak) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1UpdateSpeak. - """ - await self._send_model(message) - - async def send_inject_user_message(self, message: AgentV1InjectUserMessage) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1InjectUserMessage. - """ - await self._send_model(message) - - async def send_inject_agent_message(self, message: AgentV1InjectAgentMessage) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1InjectAgentMessage. - """ - await self._send_model(message) - - async def send_function_call_response(self, message: AgentV1SendFunctionCallResponse) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1SendFunctionCallResponse. - """ - await self._send_model(message) - - async def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1KeepAlive. - """ - await self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) - - async def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1UpdatePrompt. - """ - await self._send_model(message) - - async def send_update_think(self, message: AgentV1UpdateThink) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1UpdateThink. - """ - await self._send_model(message) - - async def send_media(self, message: bytes) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a bytes. - """ - await self._send(message) - - async def recv(self) -> V1SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = await self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - async def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - await self._websocket.send(data) - - async def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - await self._send(_sanitize_numeric_types(data.dict())) - - -class V1SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: websockets_sync_connection.Connection): - super().__init__() - self._websocket = websocket - - def __iter__(self): - for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - self._emit(EventType.OPEN, None) - try: - for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - self._emit(EventType.MESSAGE, parsed) - except Exception as exc: - self._emit(EventType.ERROR, exc) - finally: - self._emit(EventType.CLOSE, None) - - def send_settings(self, message: AgentV1Settings) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1Settings. - """ - self._send_model(message) - - def send_update_speak(self, message: AgentV1UpdateSpeak) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1UpdateSpeak. - """ - self._send_model(message) - - def send_inject_user_message(self, message: AgentV1InjectUserMessage) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1InjectUserMessage. - """ - self._send_model(message) - - def send_inject_agent_message(self, message: AgentV1InjectAgentMessage) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1InjectAgentMessage. - """ - self._send_model(message) - - def send_function_call_response(self, message: AgentV1SendFunctionCallResponse) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1SendFunctionCallResponse. - """ - self._send_model(message) - - def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1KeepAlive. - """ - self._send_model(message or AgentV1KeepAlive(type="KeepAlive")) - - def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1UpdatePrompt. - """ - self._send_model(message) - - def send_update_think(self, message: AgentV1UpdateThink) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a AgentV1UpdateThink. - """ - self._send_model(message) - - def send_media(self, message: bytes) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a bytes. - """ - self._send(message) - - def recv(self) -> V1SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - self._websocket.send(data) - - def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - self._send(_sanitize_numeric_types(data.dict())) diff --git a/src/deepgram/listen/v1/socket_client.py b/src/deepgram/listen/v1/socket_client.py index cffa82b7..5954d116 100644 --- a/src/deepgram/listen/v1/socket_client.py +++ b/src/deepgram/listen/v1/socket_client.py @@ -3,9 +3,7 @@ import json import logging import typing -from json.decoder import JSONDecodeError -import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type @@ -69,7 +67,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -81,26 +79,26 @@ async def send_media(self, message: bytes) -> None: """ await self._send(message) - async def send_finalize(self, message: ListenV1Finalize) -> None: + async def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1Finalize. """ - await self._send_model(message) + await self._send_model(message or ListenV1Finalize(type="Finalize")) - async def send_close_stream(self, message: ListenV1CloseStream) -> None: + async def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1CloseStream. """ - await self._send_model(message) + await self._send_model(message or ListenV1CloseStream(type="CloseStream")) - async def send_keep_alive(self, message: ListenV1KeepAlive) -> None: + async def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1KeepAlive. """ - await self._send_model(message) + await self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) async def recv(self) -> V1SocketClientResponse: """ @@ -174,7 +172,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -186,26 +184,26 @@ def send_media(self, message: bytes) -> None: """ self._send(message) - def send_finalize(self, message: ListenV1Finalize) -> None: + def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1Finalize. """ - self._send_model(message) + self._send_model(message or ListenV1Finalize(type="Finalize")) - def send_close_stream(self, message: ListenV1CloseStream) -> None: + def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1CloseStream. """ - self._send_model(message) + self._send_model(message or ListenV1CloseStream(type="CloseStream")) - def send_keep_alive(self, message: ListenV1KeepAlive) -> None: + def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV1KeepAlive. """ - self._send_model(message) + self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) def recv(self) -> V1SocketClientResponse: """ diff --git a/src/deepgram/listen/v1/socket_client.py.bak b/src/deepgram/listen/v1/socket_client.py.bak deleted file mode 100644 index 5954d116..00000000 --- a/src/deepgram/listen/v1/socket_client.py.bak +++ /dev/null @@ -1,234 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import json -import logging -import typing - -import websockets.sync.connection as websockets_sync_connection -from ...core.events import EventEmitterMixin, EventType -from ...core.unchecked_base_model import construct_type -from .types.listen_v1close_stream import ListenV1CloseStream -from .types.listen_v1finalize import ListenV1Finalize -from .types.listen_v1keep_alive import ListenV1KeepAlive -from .types.listen_v1metadata import ListenV1Metadata -from .types.listen_v1results import ListenV1Results -from .types.listen_v1speech_started import ListenV1SpeechStarted -from .types.listen_v1utterance_end import ListenV1UtteranceEnd - -try: - from websockets.legacy.client import WebSocketClientProtocol # type: ignore -except ImportError: - from websockets import WebSocketClientProtocol # type: ignore - -_logger = logging.getLogger(__name__) -V1SocketClientResponse = typing.Union[ListenV1Results, ListenV1Metadata, ListenV1UtteranceEnd, ListenV1SpeechStarted] - - -class AsyncV1SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: WebSocketClientProtocol): - super().__init__() - self._websocket = websocket - - async def __aiter__(self): - async for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - async def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - await self._emit_async(EventType.OPEN, None) - try: - async for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: - await self._emit_async(EventType.ERROR, exc) - finally: - await self._emit_async(EventType.CLOSE, None) - - async def send_media(self, message: bytes) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a bytes. - """ - await self._send(message) - - async def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV1Finalize. - """ - await self._send_model(message or ListenV1Finalize(type="Finalize")) - - async def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV1CloseStream. - """ - await self._send_model(message or ListenV1CloseStream(type="CloseStream")) - - async def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV1KeepAlive. - """ - await self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) - - async def recv(self) -> V1SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = await self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - async def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - await self._websocket.send(data) - - async def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - await self._send(data.dict()) - - -class V1SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: websockets_sync_connection.Connection): - super().__init__() - self._websocket = websocket - - def __iter__(self): - for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - self._emit(EventType.OPEN, None) - try: - for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - self._emit(EventType.MESSAGE, parsed) - except Exception as exc: - self._emit(EventType.ERROR, exc) - finally: - self._emit(EventType.CLOSE, None) - - def send_media(self, message: bytes) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a bytes. - """ - self._send(message) - - def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV1Finalize. - """ - self._send_model(message or ListenV1Finalize(type="Finalize")) - - def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV1CloseStream. - """ - self._send_model(message or ListenV1CloseStream(type="CloseStream")) - - def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV1KeepAlive. - """ - self._send_model(message or ListenV1KeepAlive(type="KeepAlive")) - - def recv(self) -> V1SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - self._websocket.send(data) - - def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - self._send(data.dict()) diff --git a/src/deepgram/listen/v2/socket_client.py b/src/deepgram/listen/v2/socket_client.py index 696c5938..d214f0f5 100644 --- a/src/deepgram/listen/v2/socket_client.py +++ b/src/deepgram/listen/v2/socket_client.py @@ -3,16 +3,12 @@ import json import logging import typing -from json.decoder import JSONDecodeError -import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type from .types.listen_v2close_stream import ListenV2CloseStream -from .types.listen_v2configure import ListenV2Configure from .types.listen_v2configure_failure import ListenV2ConfigureFailure -from .types.listen_v2configure_success import ListenV2ConfigureSuccess from .types.listen_v2connected import ListenV2Connected from .types.listen_v2fatal_error import ListenV2FatalError from .types.listen_v2turn_info import ListenV2TurnInfo @@ -24,7 +20,7 @@ _logger = logging.getLogger(__name__) V2SocketClientResponse = typing.Union[ - ListenV2Connected, ListenV2TurnInfo, ListenV2ConfigureSuccess, ListenV2ConfigureFailure, ListenV2FatalError + ListenV2Connected, ListenV2TurnInfo, typing.Any, ListenV2ConfigureFailure, ListenV2FatalError ] @@ -71,7 +67,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -83,19 +79,19 @@ async def send_media(self, message: bytes) -> None: """ await self._send(message) - async def send_close_stream(self, message: ListenV2CloseStream) -> None: + async def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV2CloseStream. """ - await self._send_model(message) + await self._send_model(message or ListenV2CloseStream(type="CloseStream")) - async def send_configure(self, message: ListenV2Configure) -> None: + async def send_configure(self, message: typing.Any) -> None: """ Send a message to the websocket connection. - The message will be sent as a ListenV2Configure. + The message will be sent as a typing.Any. """ - await self._send_model(message) + await self._send(message) async def recv(self) -> V2SocketClientResponse: """ @@ -169,7 +165,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -181,19 +177,19 @@ def send_media(self, message: bytes) -> None: """ self._send(message) - def send_close_stream(self, message: ListenV2CloseStream) -> None: + def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a ListenV2CloseStream. """ - self._send_model(message) + self._send_model(message or ListenV2CloseStream(type="CloseStream")) - def send_configure(self, message: ListenV2Configure) -> None: + def send_configure(self, message: typing.Any) -> None: """ Send a message to the websocket connection. - The message will be sent as a ListenV2Configure. + The message will be sent as a typing.Any. """ - self._send_model(message) + self._send(message) def recv(self) -> V2SocketClientResponse: """ diff --git a/src/deepgram/listen/v2/socket_client.py.bak b/src/deepgram/listen/v2/socket_client.py.bak deleted file mode 100644 index d214f0f5..00000000 --- a/src/deepgram/listen/v2/socket_client.py.bak +++ /dev/null @@ -1,220 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import json -import logging -import typing - -import websockets.sync.connection as websockets_sync_connection -from ...core.events import EventEmitterMixin, EventType -from ...core.unchecked_base_model import construct_type -from .types.listen_v2close_stream import ListenV2CloseStream -from .types.listen_v2configure_failure import ListenV2ConfigureFailure -from .types.listen_v2connected import ListenV2Connected -from .types.listen_v2fatal_error import ListenV2FatalError -from .types.listen_v2turn_info import ListenV2TurnInfo - -try: - from websockets.legacy.client import WebSocketClientProtocol # type: ignore -except ImportError: - from websockets import WebSocketClientProtocol # type: ignore - -_logger = logging.getLogger(__name__) -V2SocketClientResponse = typing.Union[ - ListenV2Connected, ListenV2TurnInfo, typing.Any, ListenV2ConfigureFailure, ListenV2FatalError -] - - -class AsyncV2SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: WebSocketClientProtocol): - super().__init__() - self._websocket = websocket - - async def __aiter__(self): - async for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V2SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - async def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - await self._emit_async(EventType.OPEN, None) - try: - async for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: - await self._emit_async(EventType.ERROR, exc) - finally: - await self._emit_async(EventType.CLOSE, None) - - async def send_media(self, message: bytes) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a bytes. - """ - await self._send(message) - - async def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV2CloseStream. - """ - await self._send_model(message or ListenV2CloseStream(type="CloseStream")) - - async def send_configure(self, message: typing.Any) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a typing.Any. - """ - await self._send(message) - - async def recv(self) -> V2SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = await self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - async def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - await self._websocket.send(data) - - async def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - await self._send(data.dict()) - - -class V2SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: websockets_sync_connection.Connection): - super().__init__() - self._websocket = websocket - - def __iter__(self): - for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V2SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - self._emit(EventType.OPEN, None) - try: - for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - self._emit(EventType.MESSAGE, parsed) - except Exception as exc: - self._emit(EventType.ERROR, exc) - finally: - self._emit(EventType.CLOSE, None) - - def send_media(self, message: bytes) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a bytes. - """ - self._send(message) - - def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a ListenV2CloseStream. - """ - self._send_model(message or ListenV2CloseStream(type="CloseStream")) - - def send_configure(self, message: typing.Any) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a typing.Any. - """ - self._send(message) - - def recv(self) -> V2SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V2SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - self._websocket.send(data) - - def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - self._send(data.dict()) diff --git a/src/deepgram/speak/v1/socket_client.py b/src/deepgram/speak/v1/socket_client.py index 9f1cad28..e3c28bb5 100644 --- a/src/deepgram/speak/v1/socket_client.py +++ b/src/deepgram/speak/v1/socket_client.py @@ -3,9 +3,7 @@ import json import logging import typing -from json.decoder import JSONDecodeError -import websockets import websockets.sync.connection as websockets_sync_connection from ...core.events import EventEmitterMixin, EventType from ...core.unchecked_base_model import construct_type @@ -70,7 +68,7 @@ async def start_listening(self): ) continue await self._emit_async(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: await self._emit_async(EventType.ERROR, exc) finally: await self._emit_async(EventType.CLOSE, None) @@ -82,26 +80,26 @@ async def send_text(self, message: SpeakV1Text) -> None: """ await self._send_model(message) - async def send_flush(self, message: SpeakV1Flush) -> None: + async def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Flush. """ - await self._send_model(message) + await self._send_model(message or SpeakV1Flush(type="Flush")) - async def send_clear(self, message: SpeakV1Clear) -> None: + async def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Clear. """ - await self._send_model(message) + await self._send_model(message or SpeakV1Clear(type="Clear")) - async def send_close(self, message: SpeakV1Close) -> None: + async def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Close. """ - await self._send_model(message) + await self._send_model(message or SpeakV1Close(type="Close")) async def recv(self) -> V1SocketClientResponse: """ @@ -175,7 +173,7 @@ def start_listening(self): ) continue self._emit(EventType.MESSAGE, parsed) - except (websockets.WebSocketException, JSONDecodeError) as exc: + except Exception as exc: self._emit(EventType.ERROR, exc) finally: self._emit(EventType.CLOSE, None) @@ -187,26 +185,26 @@ def send_text(self, message: SpeakV1Text) -> None: """ self._send_model(message) - def send_flush(self, message: SpeakV1Flush) -> None: + def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Flush. """ - self._send_model(message) + self._send_model(message or SpeakV1Flush(type="Flush")) - def send_clear(self, message: SpeakV1Clear) -> None: + def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Clear. """ - self._send_model(message) + self._send_model(message or SpeakV1Clear(type="Clear")) - def send_close(self, message: SpeakV1Close) -> None: + def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: """ Send a message to the websocket connection. The message will be sent as a SpeakV1Close. """ - self._send_model(message) + self._send_model(message or SpeakV1Close(type="Close")) def recv(self) -> V1SocketClientResponse: """ diff --git a/src/deepgram/speak/v1/socket_client.py.bak b/src/deepgram/speak/v1/socket_client.py.bak deleted file mode 100644 index e3c28bb5..00000000 --- a/src/deepgram/speak/v1/socket_client.py.bak +++ /dev/null @@ -1,235 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import json -import logging -import typing - -import websockets.sync.connection as websockets_sync_connection -from ...core.events import EventEmitterMixin, EventType -from ...core.unchecked_base_model import construct_type -from .types.speak_v1clear import SpeakV1Clear -from .types.speak_v1cleared import SpeakV1Cleared -from .types.speak_v1close import SpeakV1Close -from .types.speak_v1flush import SpeakV1Flush -from .types.speak_v1flushed import SpeakV1Flushed -from .types.speak_v1metadata import SpeakV1Metadata -from .types.speak_v1text import SpeakV1Text -from .types.speak_v1warning import SpeakV1Warning - -try: - from websockets.legacy.client import WebSocketClientProtocol # type: ignore -except ImportError: - from websockets import WebSocketClientProtocol # type: ignore - -_logger = logging.getLogger(__name__) -V1SocketClientResponse = typing.Union[bytes, SpeakV1Metadata, SpeakV1Flushed, SpeakV1Cleared, SpeakV1Warning] - - -class AsyncV1SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: WebSocketClientProtocol): - super().__init__() - self._websocket = websocket - - async def __aiter__(self): - async for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - async def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - await self._emit_async(EventType.OPEN, None) - try: - async for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - await self._emit_async(EventType.MESSAGE, parsed) - except Exception as exc: - await self._emit_async(EventType.ERROR, exc) - finally: - await self._emit_async(EventType.CLOSE, None) - - async def send_text(self, message: SpeakV1Text) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Text. - """ - await self._send_model(message) - - async def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Flush. - """ - await self._send_model(message or SpeakV1Flush(type="Flush")) - - async def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Clear. - """ - await self._send_model(message or SpeakV1Clear(type="Clear")) - - async def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Close. - """ - await self._send_model(message or SpeakV1Close(type="Close")) - - async def recv(self) -> V1SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = await self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - async def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - await self._websocket.send(data) - - async def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - await self._send(data.dict()) - - -class V1SocketClient(EventEmitterMixin): - def __init__(self, *, websocket: websockets_sync_connection.Connection): - super().__init__() - self._websocket = websocket - - def __iter__(self): - for message in self._websocket: - if isinstance(message, bytes): - yield message - else: - try: - yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - - def start_listening(self): - """ - Start listening for messages on the websocket connection. - - Emits events in the following order: - - EventType.OPEN when connection is established - - EventType.MESSAGE for each message received - - EventType.ERROR if an error occurs - - EventType.CLOSE when connection is closed - """ - self._emit(EventType.OPEN, None) - try: - for raw_message in self._websocket: - if isinstance(raw_message, bytes): - parsed = raw_message - else: - json_data = json.loads(raw_message) - try: - parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning( - "Skipping unknown WebSocket message; update your SDK version to support new message types." - ) - continue - self._emit(EventType.MESSAGE, parsed) - except Exception as exc: - self._emit(EventType.ERROR, exc) - finally: - self._emit(EventType.CLOSE, None) - - def send_text(self, message: SpeakV1Text) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Text. - """ - self._send_model(message) - - def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Flush. - """ - self._send_model(message or SpeakV1Flush(type="Flush")) - - def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Clear. - """ - self._send_model(message or SpeakV1Clear(type="Clear")) - - def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None: - """ - Send a message to the websocket connection. - The message will be sent as a SpeakV1Close. - """ - self._send_model(message or SpeakV1Close(type="Close")) - - def recv(self) -> V1SocketClientResponse: - """ - Receive a message from the websocket connection. - """ - data = self._websocket.recv() - if isinstance(data, bytes): - return data # type: ignore - json_data = json.loads(data) - try: - return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore - except Exception: - _logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.") - return json_data # type: ignore - - def _send(self, data: typing.Any) -> None: - """ - Send a message to the websocket connection. - """ - if isinstance(data, dict): - data = json.dumps(data) - self._websocket.send(data) - - def _send_model(self, data: typing.Any) -> None: - """ - Send a Pydantic model to the websocket connection. - """ - self._send(data.dict()) diff --git a/tests/custom/test_agent_history.py b/tests/custom/test_agent_history.py index d9cac591..01db274b 100644 --- a/tests/custom/test_agent_history.py +++ b/tests/custom/test_agent_history.py @@ -1,5 +1,5 @@ from deepgram.agent.v1.socket_client import V1SocketClientResponse -from deepgram.agent.v1.types import AgentV1HistoryContent, AgentV1HistoryFunctionCalls +from deepgram.agent.v1.types import ConversationHistoryMessage, FunctionCallHistoryMessage from deepgram.core.unchecked_base_model import construct_type @@ -9,7 +9,7 @@ def test_agent_history_content_parses_from_socket_union() -> None: object_={"type": "History", "role": "user", "content": "hello"}, ) - assert isinstance(parsed, AgentV1HistoryContent) + assert isinstance(parsed, ConversationHistoryMessage) assert parsed.type == "History" assert parsed.role == "user" assert parsed.content == "hello" @@ -32,7 +32,7 @@ def test_agent_history_function_calls_parse_from_socket_union() -> None: }, ) - assert isinstance(parsed, AgentV1HistoryFunctionCalls) + assert isinstance(parsed, FunctionCallHistoryMessage) assert parsed.type == "History" assert len(parsed.function_calls) == 1 From 8efa5e26a368f274aab401cce33352a9dda3e8c3 Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 29 Apr 2026 16:12:03 +0100 Subject: [PATCH 5/6] fix: preserve backwards compatibility after SDK regeneration Restore legacy agent-history and create-key request aliases on top of the regenerated types, add compatibility coverage, and update regen docs/freeze rules so future Fern runs keep the shims intact. --- .fernignore | 14 + AGENTS.md | 4 + src/deepgram/__init__.py | 3 + src/deepgram/agent/__init__.py | 24 + src/deepgram/agent/v1/__init__.py | 24 + src/deepgram/agent/v1/requests/__init__.py | 14 + .../v1/requests/agent_v1history_content.py | 5 + .../agent_v1history_function_calls.py | 5 + ...ngs_agent_context_messages_item_content.py | 5 + ...nt_context_messages_item_function_calls.py | 5 + src/deepgram/agent/v1/types/__init__.py | 14 + .../agent/v1/types/agent_v1history_content.py | 5 + .../types/agent_v1history_function_calls.py | 5 + ...ngs_agent_context_messages_item_content.py | 5 + ...nt_context_messages_item_function_calls.py | 5 + src/deepgram/requests/__init__.py | 3 + .../requests/create_key_v1request_one.py | 5 + src/deepgram/types/__init__.py | 3 + .../types/create_key_v1request_one.py | 5 + tests/custom/test_compat_aliases.py | 145 ++++++ tests/typecheck/compat_aliases.py | 32 ++ tests/wire/test_manage_v1_projects_keys.py | 14 + uv.lock | 479 ++++++++++++++++++ 23 files changed, 823 insertions(+) create mode 100644 src/deepgram/agent/v1/requests/agent_v1history_content.py create mode 100644 src/deepgram/agent/v1/requests/agent_v1history_function_calls.py create mode 100644 src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py create mode 100644 src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py create mode 100644 src/deepgram/agent/v1/types/agent_v1history_content.py create mode 100644 src/deepgram/agent/v1/types/agent_v1history_function_calls.py create mode 100644 src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py create mode 100644 src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py create mode 100644 src/deepgram/requests/create_key_v1request_one.py create mode 100644 src/deepgram/types/create_key_v1request_one.py create mode 100644 tests/custom/test_compat_aliases.py create mode 100644 tests/typecheck/compat_aliases.py create mode 100644 uv.lock diff --git a/.fernignore b/.fernignore index 642889b3..ab51029b 100644 --- a/.fernignore +++ b/.fernignore @@ -17,8 +17,22 @@ src/deepgram/listen/v1/socket_client.py src/deepgram/listen/v2/socket_client.py src/deepgram/speak/v1/socket_client.py +# Backward-compatibility alias shims for renamed generated public types/params. +# These are hand-written wrappers around the current generated names and must not be regenerated. +src/deepgram/agent/v1/types/agent_v1history_content.py +src/deepgram/agent/v1/types/agent_v1history_function_calls.py +src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py +src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py +src/deepgram/agent/v1/requests/agent_v1history_content.py +src/deepgram/agent/v1/requests/agent_v1history_function_calls.py +src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py +src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py +src/deepgram/types/create_key_v1request_one.py +src/deepgram/requests/create_key_v1request_one.py + # Hand-written custom tests tests/custom/test_agent_history.py +tests/custom/test_compat_aliases.py tests/custom/test_text_builder.py tests/custom/test_transport.py diff --git a/AGENTS.md b/AGENTS.md index ffb21162..a8d76aa1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,8 +24,12 @@ How to identify: Current permanently frozen files: - `src/deepgram/client.py` — entirely custom (Bearer auth, session ID); no Fern equivalent - `src/deepgram/helpers/` — hand-written TextBuilder helpers +- `src/deepgram/agent/v1/types/agent_v1history_content.py`, `src/deepgram/agent/v1/types/agent_v1history_function_calls.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py` — hand-written compatibility aliases preserving old public Agent History type imports after regen renames +- `src/deepgram/agent/v1/requests/agent_v1history_content.py`, `src/deepgram/agent/v1/requests/agent_v1history_function_calls.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py` — hand-written compatibility aliases preserving old public Agent History request-param imports after regen renames +- `src/deepgram/types/create_key_v1request_one.py`, `src/deepgram/requests/create_key_v1request_one.py` — hand-written compatibility aliases preserving the old public create-key request imports after the regen rename to `CreateKeyV1Request` - `src/deepgram/transport_interface.py`, `src/deepgram/transport.py`, `src/deepgram/transports/` — custom transport layer - `tests/custom/test_agent_history.py` — hand-written regression test for Agent History websocket payload parsing +- `tests/custom/test_compat_aliases.py` — hand-written regression test for backward-compatible alias imports after regen renames - `tests/custom/test_text_builder.py`, `tests/custom/test_transport.py` — hand-written tests - `tests/manual/` — manual standalone tests - `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, `reference.md` — docs diff --git a/src/deepgram/__init__.py b/src/deepgram/__init__.py index 5a767214..f7fe77c0 100644 --- a/src/deepgram/__init__.py +++ b/src/deepgram/__init__.py @@ -39,6 +39,7 @@ CartesiaSpeakProviderVoice, CreateAgentConfigurationV1Response, CreateKeyV1Request, + CreateKeyV1RequestOne, CreateKeyV1Response, CreateProjectDistributionCredentialsV1Response, CreateProjectDistributionCredentialsV1ResponseDistributionCredentials, @@ -467,6 +468,7 @@ "CreateAgentConfigurationV1Response": ".types", "CreateAgentConfigurationV1ResponseParams": ".requests", "CreateKeyV1Request": ".types", + "CreateKeyV1RequestOne": ".types", "CreateKeyV1RequestParams": ".requests", "CreateKeyV1Response": ".types", "CreateKeyV1ResponseParams": ".requests", @@ -902,6 +904,7 @@ def __dir__(): "CreateAgentConfigurationV1Response", "CreateAgentConfigurationV1ResponseParams", "CreateKeyV1Request", + "CreateKeyV1RequestOne", "CreateKeyV1RequestParams", "CreateKeyV1Response", "CreateKeyV1ResponseParams", diff --git a/src/deepgram/agent/__init__.py b/src/deepgram/agent/__init__.py index 4c2fae13..81dcbfa0 100644 --- a/src/deepgram/agent/__init__.py +++ b/src/deepgram/agent/__init__.py @@ -24,9 +24,13 @@ AgentV1FunctionCallRequestFunctionsItemParams, AgentV1FunctionCallRequestParams, AgentV1History, + AgentV1HistoryContent, + AgentV1HistoryContentParams, AgentV1HistoryContentRole, + AgentV1HistoryFunctionCalls, AgentV1HistoryFunctionCallsFunctionCallsItem, AgentV1HistoryFunctionCallsFunctionCallsItemParams, + AgentV1HistoryFunctionCallsParams, AgentV1HistoryParams, AgentV1InjectAgentMessage, AgentV1InjectAgentMessageBehavior, @@ -47,9 +51,13 @@ AgentV1SettingsAgent, AgentV1SettingsAgentContext, AgentV1SettingsAgentContextMessagesItem, + AgentV1SettingsAgentContextMessagesItemContent, + AgentV1SettingsAgentContextMessagesItemContentParams, AgentV1SettingsAgentContextMessagesItemContentRole, + AgentV1SettingsAgentContextMessagesItemFunctionCalls, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams, + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, AgentV1SettingsAgentContextMessagesItemParams, AgentV1SettingsAgentContextParams, AgentV1SettingsAgentListen, @@ -124,9 +132,13 @@ "AgentV1FunctionCallRequestFunctionsItemParams": ".v1", "AgentV1FunctionCallRequestParams": ".v1", "AgentV1History": ".v1", + "AgentV1HistoryContent": ".v1", + "AgentV1HistoryContentParams": ".v1", "AgentV1HistoryContentRole": ".v1", + "AgentV1HistoryFunctionCalls": ".v1", "AgentV1HistoryFunctionCallsFunctionCallsItem": ".v1", "AgentV1HistoryFunctionCallsFunctionCallsItemParams": ".v1", + "AgentV1HistoryFunctionCallsParams": ".v1", "AgentV1HistoryParams": ".v1", "AgentV1InjectAgentMessage": ".v1", "AgentV1InjectAgentMessageBehavior": ".v1", @@ -147,9 +159,13 @@ "AgentV1SettingsAgent": ".v1", "AgentV1SettingsAgentContext": ".v1", "AgentV1SettingsAgentContextMessagesItem": ".v1", + "AgentV1SettingsAgentContextMessagesItemContent": ".v1", + "AgentV1SettingsAgentContextMessagesItemContentParams": ".v1", "AgentV1SettingsAgentContextMessagesItemContentRole": ".v1", + "AgentV1SettingsAgentContextMessagesItemFunctionCalls": ".v1", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem": ".v1", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams": ".v1", + "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams": ".v1", "AgentV1SettingsAgentContextMessagesItemParams": ".v1", "AgentV1SettingsAgentContextParams": ".v1", "AgentV1SettingsAgentListen": ".v1", @@ -248,9 +264,13 @@ def __dir__(): "AgentV1FunctionCallRequestFunctionsItemParams", "AgentV1FunctionCallRequestParams", "AgentV1History", + "AgentV1HistoryContent", + "AgentV1HistoryContentParams", "AgentV1HistoryContentRole", + "AgentV1HistoryFunctionCalls", "AgentV1HistoryFunctionCallsFunctionCallsItem", "AgentV1HistoryFunctionCallsFunctionCallsItemParams", + "AgentV1HistoryFunctionCallsParams", "AgentV1HistoryParams", "AgentV1InjectAgentMessage", "AgentV1InjectAgentMessageBehavior", @@ -271,9 +291,13 @@ def __dir__(): "AgentV1SettingsAgent", "AgentV1SettingsAgentContext", "AgentV1SettingsAgentContextMessagesItem", + "AgentV1SettingsAgentContextMessagesItemContent", + "AgentV1SettingsAgentContextMessagesItemContentParams", "AgentV1SettingsAgentContextMessagesItemContentRole", + "AgentV1SettingsAgentContextMessagesItemFunctionCalls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams", + "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams", "AgentV1SettingsAgentContextMessagesItemParams", "AgentV1SettingsAgentContextParams", "AgentV1SettingsAgentListen", diff --git a/src/deepgram/agent/v1/__init__.py b/src/deepgram/agent/v1/__init__.py index 8e85426d..31bd1db4 100644 --- a/src/deepgram/agent/v1/__init__.py +++ b/src/deepgram/agent/v1/__init__.py @@ -16,7 +16,9 @@ AgentV1FunctionCallRequest, AgentV1FunctionCallRequestFunctionsItem, AgentV1History, + AgentV1HistoryContent, AgentV1HistoryContentRole, + AgentV1HistoryFunctionCalls, AgentV1HistoryFunctionCallsFunctionCallsItem, AgentV1InjectAgentMessage, AgentV1InjectAgentMessageBehavior, @@ -30,7 +32,9 @@ AgentV1SettingsAgent, AgentV1SettingsAgentContext, AgentV1SettingsAgentContextMessagesItem, + AgentV1SettingsAgentContextMessagesItemContent, AgentV1SettingsAgentContextMessagesItemContentRole, + AgentV1SettingsAgentContextMessagesItemFunctionCalls, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem, AgentV1SettingsAgentListen, AgentV1SettingsAgentListenProvider, @@ -69,7 +73,9 @@ AgentV1ErrorParams, AgentV1FunctionCallRequestFunctionsItemParams, AgentV1FunctionCallRequestParams, + AgentV1HistoryContentParams, AgentV1HistoryFunctionCallsFunctionCallsItemParams, + AgentV1HistoryFunctionCallsParams, AgentV1HistoryParams, AgentV1InjectAgentMessageParams, AgentV1InjectUserMessageParams, @@ -79,6 +85,8 @@ AgentV1ReceiveFunctionCallResponseParams, AgentV1SendFunctionCallResponseParams, AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams, + AgentV1SettingsAgentContextMessagesItemContentParams, + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, AgentV1SettingsAgentContextMessagesItemParams, AgentV1SettingsAgentContextParams, AgentV1SettingsAgentListenParams, @@ -126,9 +134,13 @@ "AgentV1FunctionCallRequestFunctionsItemParams": ".requests", "AgentV1FunctionCallRequestParams": ".requests", "AgentV1History": ".types", + "AgentV1HistoryContent": ".types", + "AgentV1HistoryContentParams": ".requests", "AgentV1HistoryContentRole": ".types", + "AgentV1HistoryFunctionCalls": ".types", "AgentV1HistoryFunctionCallsFunctionCallsItem": ".types", "AgentV1HistoryFunctionCallsFunctionCallsItemParams": ".requests", + "AgentV1HistoryFunctionCallsParams": ".requests", "AgentV1HistoryParams": ".requests", "AgentV1InjectAgentMessage": ".types", "AgentV1InjectAgentMessageBehavior": ".types", @@ -149,9 +161,13 @@ "AgentV1SettingsAgent": ".types", "AgentV1SettingsAgentContext": ".types", "AgentV1SettingsAgentContextMessagesItem": ".types", + "AgentV1SettingsAgentContextMessagesItemContent": ".types", + "AgentV1SettingsAgentContextMessagesItemContentParams": ".requests", "AgentV1SettingsAgentContextMessagesItemContentRole": ".types", + "AgentV1SettingsAgentContextMessagesItemFunctionCalls": ".types", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem": ".types", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams": ".requests", + "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams": ".requests", "AgentV1SettingsAgentContextMessagesItemParams": ".requests", "AgentV1SettingsAgentContextParams": ".requests", "AgentV1SettingsAgentListen": ".types", @@ -250,9 +266,13 @@ def __dir__(): "AgentV1FunctionCallRequestFunctionsItemParams", "AgentV1FunctionCallRequestParams", "AgentV1History", + "AgentV1HistoryContent", + "AgentV1HistoryContentParams", "AgentV1HistoryContentRole", + "AgentV1HistoryFunctionCalls", "AgentV1HistoryFunctionCallsFunctionCallsItem", "AgentV1HistoryFunctionCallsFunctionCallsItemParams", + "AgentV1HistoryFunctionCallsParams", "AgentV1HistoryParams", "AgentV1InjectAgentMessage", "AgentV1InjectAgentMessageBehavior", @@ -273,9 +293,13 @@ def __dir__(): "AgentV1SettingsAgent", "AgentV1SettingsAgentContext", "AgentV1SettingsAgentContextMessagesItem", + "AgentV1SettingsAgentContextMessagesItemContent", + "AgentV1SettingsAgentContextMessagesItemContentParams", "AgentV1SettingsAgentContextMessagesItemContentRole", + "AgentV1SettingsAgentContextMessagesItemFunctionCalls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams", + "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams", "AgentV1SettingsAgentContextMessagesItemParams", "AgentV1SettingsAgentContextParams", "AgentV1SettingsAgentListen", diff --git a/src/deepgram/agent/v1/requests/__init__.py b/src/deepgram/agent/v1/requests/__init__.py index 3eb12d59..6c6fc0e6 100644 --- a/src/deepgram/agent/v1/requests/__init__.py +++ b/src/deepgram/agent/v1/requests/__init__.py @@ -14,6 +14,8 @@ from .agent_v1function_call_request import AgentV1FunctionCallRequestParams from .agent_v1function_call_request_functions_item import AgentV1FunctionCallRequestFunctionsItemParams from .agent_v1history import AgentV1HistoryParams + from .agent_v1history_content import AgentV1HistoryContentParams + from .agent_v1history_function_calls import AgentV1HistoryFunctionCallsParams from .agent_v1history_function_calls_function_calls_item import AgentV1HistoryFunctionCallsFunctionCallsItemParams from .agent_v1inject_agent_message import AgentV1InjectAgentMessageParams from .agent_v1inject_user_message import AgentV1InjectUserMessageParams @@ -26,6 +28,10 @@ from .agent_v1settings_agent import AgentV1SettingsAgentParams from .agent_v1settings_agent_context import AgentV1SettingsAgentContextParams from .agent_v1settings_agent_context_messages_item import AgentV1SettingsAgentContextMessagesItemParams + from .agent_v1settings_agent_context_messages_item_content import AgentV1SettingsAgentContextMessagesItemContentParams + from .agent_v1settings_agent_context_messages_item_function_calls import ( + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, + ) from .agent_v1settings_agent_context_messages_item_function_calls_function_calls_item import ( AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams, ) @@ -64,7 +70,9 @@ "AgentV1ErrorParams": ".agent_v1error", "AgentV1FunctionCallRequestFunctionsItemParams": ".agent_v1function_call_request_functions_item", "AgentV1FunctionCallRequestParams": ".agent_v1function_call_request", + "AgentV1HistoryContentParams": ".agent_v1history_content", "AgentV1HistoryFunctionCallsFunctionCallsItemParams": ".agent_v1history_function_calls_function_calls_item", + "AgentV1HistoryFunctionCallsParams": ".agent_v1history_function_calls", "AgentV1HistoryParams": ".agent_v1history", "AgentV1InjectAgentMessageParams": ".agent_v1inject_agent_message", "AgentV1InjectUserMessageParams": ".agent_v1inject_user_message", @@ -74,6 +82,8 @@ "AgentV1ReceiveFunctionCallResponseParams": ".agent_v1receive_function_call_response", "AgentV1SendFunctionCallResponseParams": ".agent_v1send_function_call_response", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams": ".agent_v1settings_agent_context_messages_item_function_calls_function_calls_item", + "AgentV1SettingsAgentContextMessagesItemContentParams": ".agent_v1settings_agent_context_messages_item_content", + "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams": ".agent_v1settings_agent_context_messages_item_function_calls", "AgentV1SettingsAgentContextMessagesItemParams": ".agent_v1settings_agent_context_messages_item", "AgentV1SettingsAgentContextParams": ".agent_v1settings_agent_context", "AgentV1SettingsAgentListenParams": ".agent_v1settings_agent_listen", @@ -135,7 +145,9 @@ def __dir__(): "AgentV1ErrorParams", "AgentV1FunctionCallRequestFunctionsItemParams", "AgentV1FunctionCallRequestParams", + "AgentV1HistoryContentParams", "AgentV1HistoryFunctionCallsFunctionCallsItemParams", + "AgentV1HistoryFunctionCallsParams", "AgentV1HistoryParams", "AgentV1InjectAgentMessageParams", "AgentV1InjectUserMessageParams", @@ -145,6 +157,8 @@ def __dir__(): "AgentV1ReceiveFunctionCallResponseParams", "AgentV1SendFunctionCallResponseParams", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItemParams", + "AgentV1SettingsAgentContextMessagesItemContentParams", + "AgentV1SettingsAgentContextMessagesItemFunctionCallsParams", "AgentV1SettingsAgentContextMessagesItemParams", "AgentV1SettingsAgentContextParams", "AgentV1SettingsAgentListenParams", diff --git a/src/deepgram/agent/v1/requests/agent_v1history_content.py b/src/deepgram/agent/v1/requests/agent_v1history_content.py new file mode 100644 index 00000000..a885b9bd --- /dev/null +++ b/src/deepgram/agent/v1/requests/agent_v1history_content.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .conversation_history_message import ConversationHistoryMessageParams + +AgentV1HistoryContentParams = ConversationHistoryMessageParams diff --git a/src/deepgram/agent/v1/requests/agent_v1history_function_calls.py b/src/deepgram/agent/v1/requests/agent_v1history_function_calls.py new file mode 100644 index 00000000..21f1c817 --- /dev/null +++ b/src/deepgram/agent/v1/requests/agent_v1history_function_calls.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .function_call_history_message import FunctionCallHistoryMessageParams + +AgentV1HistoryFunctionCallsParams = FunctionCallHistoryMessageParams diff --git a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py b/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py new file mode 100644 index 00000000..06512b37 --- /dev/null +++ b/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .conversation_history_message import ConversationHistoryMessageParams + +AgentV1SettingsAgentContextMessagesItemContentParams = ConversationHistoryMessageParams diff --git a/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py b/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py new file mode 100644 index 00000000..2a37f1e5 --- /dev/null +++ b/src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .function_call_history_message import FunctionCallHistoryMessageParams + +AgentV1SettingsAgentContextMessagesItemFunctionCallsParams = FunctionCallHistoryMessageParams diff --git a/src/deepgram/agent/v1/types/__init__.py b/src/deepgram/agent/v1/types/__init__.py index 15118c7a..7a6da0d6 100644 --- a/src/deepgram/agent/v1/types/__init__.py +++ b/src/deepgram/agent/v1/types/__init__.py @@ -15,7 +15,9 @@ from .agent_v1function_call_request import AgentV1FunctionCallRequest from .agent_v1function_call_request_functions_item import AgentV1FunctionCallRequestFunctionsItem from .agent_v1history import AgentV1History + from .agent_v1history_content import AgentV1HistoryContent from .agent_v1history_content_role import AgentV1HistoryContentRole + from .agent_v1history_function_calls import AgentV1HistoryFunctionCalls from .agent_v1history_function_calls_function_calls_item import AgentV1HistoryFunctionCallsFunctionCallsItem from .agent_v1inject_agent_message import AgentV1InjectAgentMessage from .agent_v1inject_agent_message_behavior import AgentV1InjectAgentMessageBehavior @@ -29,9 +31,13 @@ from .agent_v1settings_agent import AgentV1SettingsAgent from .agent_v1settings_agent_context import AgentV1SettingsAgentContext from .agent_v1settings_agent_context_messages_item import AgentV1SettingsAgentContextMessagesItem + from .agent_v1settings_agent_context_messages_item_content import AgentV1SettingsAgentContextMessagesItemContent from .agent_v1settings_agent_context_messages_item_content_role import ( AgentV1SettingsAgentContextMessagesItemContentRole, ) + from .agent_v1settings_agent_context_messages_item_function_calls import ( + AgentV1SettingsAgentContextMessagesItemFunctionCalls, + ) from .agent_v1settings_agent_context_messages_item_function_calls_function_calls_item import ( AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem, ) @@ -74,7 +80,9 @@ "AgentV1FunctionCallRequest": ".agent_v1function_call_request", "AgentV1FunctionCallRequestFunctionsItem": ".agent_v1function_call_request_functions_item", "AgentV1History": ".agent_v1history", + "AgentV1HistoryContent": ".agent_v1history_content", "AgentV1HistoryContentRole": ".agent_v1history_content_role", + "AgentV1HistoryFunctionCalls": ".agent_v1history_function_calls", "AgentV1HistoryFunctionCallsFunctionCallsItem": ".agent_v1history_function_calls_function_calls_item", "AgentV1InjectAgentMessage": ".agent_v1inject_agent_message", "AgentV1InjectAgentMessageBehavior": ".agent_v1inject_agent_message_behavior", @@ -88,7 +96,9 @@ "AgentV1SettingsAgent": ".agent_v1settings_agent", "AgentV1SettingsAgentContext": ".agent_v1settings_agent_context", "AgentV1SettingsAgentContextMessagesItem": ".agent_v1settings_agent_context_messages_item", + "AgentV1SettingsAgentContextMessagesItemContent": ".agent_v1settings_agent_context_messages_item_content", "AgentV1SettingsAgentContextMessagesItemContentRole": ".agent_v1settings_agent_context_messages_item_content_role", + "AgentV1SettingsAgentContextMessagesItemFunctionCalls": ".agent_v1settings_agent_context_messages_item_function_calls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem": ".agent_v1settings_agent_context_messages_item_function_calls_function_calls_item", "AgentV1SettingsAgentListen": ".agent_v1settings_agent_listen", "AgentV1SettingsAgentListenProvider": ".agent_v1settings_agent_listen_provider", @@ -151,7 +161,9 @@ def __dir__(): "AgentV1FunctionCallRequest", "AgentV1FunctionCallRequestFunctionsItem", "AgentV1History", + "AgentV1HistoryContent", "AgentV1HistoryContentRole", + "AgentV1HistoryFunctionCalls", "AgentV1HistoryFunctionCallsFunctionCallsItem", "AgentV1InjectAgentMessage", "AgentV1InjectAgentMessageBehavior", @@ -165,7 +177,9 @@ def __dir__(): "AgentV1SettingsAgent", "AgentV1SettingsAgentContext", "AgentV1SettingsAgentContextMessagesItem", + "AgentV1SettingsAgentContextMessagesItemContent", "AgentV1SettingsAgentContextMessagesItemContentRole", + "AgentV1SettingsAgentContextMessagesItemFunctionCalls", "AgentV1SettingsAgentContextMessagesItemFunctionCallsFunctionCallsItem", "AgentV1SettingsAgentListen", "AgentV1SettingsAgentListenProvider", diff --git a/src/deepgram/agent/v1/types/agent_v1history_content.py b/src/deepgram/agent/v1/types/agent_v1history_content.py new file mode 100644 index 00000000..19a388ba --- /dev/null +++ b/src/deepgram/agent/v1/types/agent_v1history_content.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .conversation_history_message import ConversationHistoryMessage + +AgentV1HistoryContent = ConversationHistoryMessage diff --git a/src/deepgram/agent/v1/types/agent_v1history_function_calls.py b/src/deepgram/agent/v1/types/agent_v1history_function_calls.py new file mode 100644 index 00000000..34639051 --- /dev/null +++ b/src/deepgram/agent/v1/types/agent_v1history_function_calls.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .function_call_history_message import FunctionCallHistoryMessage + +AgentV1HistoryFunctionCalls = FunctionCallHistoryMessage diff --git a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py b/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py new file mode 100644 index 00000000..d2543faf --- /dev/null +++ b/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .conversation_history_message import ConversationHistoryMessage + +AgentV1SettingsAgentContextMessagesItemContent = ConversationHistoryMessage diff --git a/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py b/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py new file mode 100644 index 00000000..2a2f67b2 --- /dev/null +++ b/src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .function_call_history_message import FunctionCallHistoryMessage + +AgentV1SettingsAgentContextMessagesItemFunctionCalls = FunctionCallHistoryMessage diff --git a/src/deepgram/requests/__init__.py b/src/deepgram/requests/__init__.py index 31a9e826..78cd5f29 100644 --- a/src/deepgram/requests/__init__.py +++ b/src/deepgram/requests/__init__.py @@ -28,6 +28,7 @@ from .cartesia_speak_provider_voice import CartesiaSpeakProviderVoiceParams from .create_agent_configuration_v1response import CreateAgentConfigurationV1ResponseParams from .create_key_v1request import CreateKeyV1RequestParams + from .create_key_v1request_one import CreateKeyV1RequestOneParams from .create_key_v1response import CreateKeyV1ResponseParams from .create_project_distribution_credentials_v1response import CreateProjectDistributionCredentialsV1ResponseParams from .create_project_distribution_credentials_v1response_distribution_credentials import ( @@ -237,6 +238,7 @@ "CartesiaSpeakProviderVoiceParams": ".cartesia_speak_provider_voice", "CreateAgentConfigurationV1ResponseParams": ".create_agent_configuration_v1response", "CreateKeyV1RequestParams": ".create_key_v1request", + "CreateKeyV1RequestOneParams": ".create_key_v1request_one", "CreateKeyV1ResponseParams": ".create_key_v1response", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentialsParams": ".create_project_distribution_credentials_v1response_distribution_credentials", "CreateProjectDistributionCredentialsV1ResponseMemberParams": ".create_project_distribution_credentials_v1response_member", @@ -428,6 +430,7 @@ def __dir__(): "CartesiaSpeakProviderVoiceParams", "CreateAgentConfigurationV1ResponseParams", "CreateKeyV1RequestParams", + "CreateKeyV1RequestOneParams", "CreateKeyV1ResponseParams", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentialsParams", "CreateProjectDistributionCredentialsV1ResponseMemberParams", diff --git a/src/deepgram/requests/create_key_v1request_one.py b/src/deepgram/requests/create_key_v1request_one.py new file mode 100644 index 00000000..34d149b7 --- /dev/null +++ b/src/deepgram/requests/create_key_v1request_one.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .create_key_v1request import CreateKeyV1RequestParams + +CreateKeyV1RequestOneParams = CreateKeyV1RequestParams diff --git a/src/deepgram/types/__init__.py b/src/deepgram/types/__init__.py index 463da29f..ce56377d 100644 --- a/src/deepgram/types/__init__.py +++ b/src/deepgram/types/__init__.py @@ -38,6 +38,7 @@ from .cartesia_speak_provider_voice import CartesiaSpeakProviderVoice from .create_agent_configuration_v1response import CreateAgentConfigurationV1Response from .create_key_v1request import CreateKeyV1Request + from .create_key_v1request_one import CreateKeyV1RequestOne from .create_key_v1response import CreateKeyV1Response from .create_project_distribution_credentials_v1response import CreateProjectDistributionCredentialsV1Response from .create_project_distribution_credentials_v1response_distribution_credentials import ( @@ -306,6 +307,7 @@ "CartesiaSpeakProviderVoice": ".cartesia_speak_provider_voice", "CreateAgentConfigurationV1Response": ".create_agent_configuration_v1response", "CreateKeyV1Request": ".create_key_v1request", + "CreateKeyV1RequestOne": ".create_key_v1request_one", "CreateKeyV1Response": ".create_key_v1response", "CreateProjectDistributionCredentialsV1Response": ".create_project_distribution_credentials_v1response", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentials": ".create_project_distribution_credentials_v1response_distribution_credentials", @@ -560,6 +562,7 @@ def __dir__(): "CartesiaSpeakProviderVoice", "CreateAgentConfigurationV1Response", "CreateKeyV1Request", + "CreateKeyV1RequestOne", "CreateKeyV1Response", "CreateProjectDistributionCredentialsV1Response", "CreateProjectDistributionCredentialsV1ResponseDistributionCredentials", diff --git a/src/deepgram/types/create_key_v1request_one.py b/src/deepgram/types/create_key_v1request_one.py new file mode 100644 index 00000000..827b04dc --- /dev/null +++ b/src/deepgram/types/create_key_v1request_one.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .create_key_v1request import CreateKeyV1Request + +CreateKeyV1RequestOne = CreateKeyV1Request diff --git a/tests/custom/test_compat_aliases.py b/tests/custom/test_compat_aliases.py new file mode 100644 index 00000000..1e1315f9 --- /dev/null +++ b/tests/custom/test_compat_aliases.py @@ -0,0 +1,145 @@ +from deepgram import CreateKeyV1Request as RootCreateKeyV1Request +from deepgram import CreateKeyV1RequestOne +from deepgram.agent import AgentV1HistoryContent as AgentHistoryContentFromAgent +from deepgram.agent import AgentV1HistoryContentParams as AgentHistoryContentParamsFromAgent +from deepgram.agent import AgentV1HistoryFunctionCalls as AgentHistoryFunctionCallsFromAgent +from deepgram.agent import AgentV1HistoryFunctionCallsParams as AgentHistoryFunctionCallsParamsFromAgent +from deepgram.agent import AgentV1SettingsAgentContextMessagesItemContent as AgentContextContentFromAgent +from deepgram.agent import AgentV1SettingsAgentContextMessagesItemContentParams as AgentContextContentParamsFromAgent +from deepgram.agent import AgentV1SettingsAgentContextMessagesItemFunctionCalls as AgentContextFunctionCallsFromAgent +from deepgram.agent import ( + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams as AgentContextFunctionCallsParamsFromAgent, +) +from deepgram.agent.v1 import AgentV1HistoryContent as AgentHistoryContentFromV1 +from deepgram.agent.v1 import AgentV1HistoryContentParams as AgentHistoryContentParamsFromV1 +from deepgram.agent.v1 import AgentV1HistoryFunctionCalls as AgentHistoryFunctionCallsFromV1 +from deepgram.agent.v1 import AgentV1HistoryFunctionCallsParams as AgentHistoryFunctionCallsParamsFromV1 +from deepgram.agent.v1 import AgentV1SettingsAgentContextMessagesItemContent as AgentContextContentFromV1 +from deepgram.agent.v1 import AgentV1SettingsAgentContextMessagesItemContentParams as AgentContextContentParamsFromV1 +from deepgram.agent.v1 import AgentV1SettingsAgentContextMessagesItemFunctionCalls as AgentContextFunctionCallsFromV1 +from deepgram.agent.v1 import ( + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams as AgentContextFunctionCallsParamsFromV1, +) +from deepgram.agent.v1.requests import ( + AgentV1HistoryContentParams, + AgentV1HistoryFunctionCallsParams, + AgentV1SettingsAgentContextMessagesItemContentParams, + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams, + ConversationHistoryMessageParams, + FunctionCallHistoryMessageParams, +) +from deepgram.agent.v1.requests.agent_v1history_content import AgentV1HistoryContentParams as ModuleHistoryContentParams +from deepgram.agent.v1.requests.agent_v1history_function_calls import ( + AgentV1HistoryFunctionCallsParams as ModuleHistoryFunctionCallsParams, +) +from deepgram.agent.v1.requests.agent_v1settings_agent_context_messages_item_content import ( + AgentV1SettingsAgentContextMessagesItemContentParams as ModuleContextContentParams, +) +from deepgram.agent.v1.requests.agent_v1settings_agent_context_messages_item_function_calls import ( + AgentV1SettingsAgentContextMessagesItemFunctionCallsParams as ModuleContextFunctionCallsParams, +) +from deepgram.agent.v1.types import ( + AgentV1HistoryContent, + AgentV1HistoryFunctionCalls, + AgentV1SettingsAgentContextMessagesItemContent, + AgentV1SettingsAgentContextMessagesItemFunctionCalls, + ConversationHistoryMessage, + FunctionCallHistoryMessage, +) +from deepgram.agent.v1.types.agent_v1history_content import AgentV1HistoryContent as ModuleHistoryContent +from deepgram.agent.v1.types.agent_v1history_function_calls import ( + AgentV1HistoryFunctionCalls as ModuleHistoryFunctionCalls, +) +from deepgram.agent.v1.types.agent_v1settings_agent_context_messages_item_content import ( + AgentV1SettingsAgentContextMessagesItemContent as ModuleContextContent, +) +from deepgram.agent.v1.types.agent_v1settings_agent_context_messages_item_function_calls import ( + AgentV1SettingsAgentContextMessagesItemFunctionCalls as ModuleContextFunctionCalls, +) +from deepgram.requests import CreateKeyV1RequestOneParams, CreateKeyV1RequestParams +from deepgram.requests.create_key_v1request_one import CreateKeyV1RequestOneParams as ModuleCreateKeyV1RequestOneParams +from deepgram.types import CreateKeyV1Request +from deepgram.types import CreateKeyV1RequestOne as CreateKeyV1RequestOneType +from deepgram.types.create_key_v1request_one import CreateKeyV1RequestOne as ModuleCreateKeyV1RequestOne + + +def test_old_agent_history_type_aliases_resolve_to_new_models() -> None: + assert AgentV1HistoryContent is ConversationHistoryMessage + assert ModuleHistoryContent is ConversationHistoryMessage + assert AgentHistoryContentFromV1 is ConversationHistoryMessage + assert AgentHistoryContentFromAgent is ConversationHistoryMessage + + assert AgentV1HistoryFunctionCalls is FunctionCallHistoryMessage + assert ModuleHistoryFunctionCalls is FunctionCallHistoryMessage + assert AgentHistoryFunctionCallsFromV1 is FunctionCallHistoryMessage + assert AgentHistoryFunctionCallsFromAgent is FunctionCallHistoryMessage + + assert AgentV1SettingsAgentContextMessagesItemContent is ConversationHistoryMessage + assert ModuleContextContent is ConversationHistoryMessage + assert AgentContextContentFromV1 is ConversationHistoryMessage + assert AgentContextContentFromAgent is ConversationHistoryMessage + + assert AgentV1SettingsAgentContextMessagesItemFunctionCalls is FunctionCallHistoryMessage + assert ModuleContextFunctionCalls is FunctionCallHistoryMessage + assert AgentContextFunctionCallsFromV1 is FunctionCallHistoryMessage + assert AgentContextFunctionCallsFromAgent is FunctionCallHistoryMessage + + +def test_old_agent_history_request_aliases_resolve_to_new_params() -> None: + assert AgentV1HistoryContentParams is ConversationHistoryMessageParams + assert ModuleHistoryContentParams is ConversationHistoryMessageParams + assert AgentHistoryContentParamsFromV1 is ConversationHistoryMessageParams + assert AgentHistoryContentParamsFromAgent is ConversationHistoryMessageParams + + assert AgentV1HistoryFunctionCallsParams is FunctionCallHistoryMessageParams + assert ModuleHistoryFunctionCallsParams is FunctionCallHistoryMessageParams + assert AgentHistoryFunctionCallsParamsFromV1 is FunctionCallHistoryMessageParams + assert AgentHistoryFunctionCallsParamsFromAgent is FunctionCallHistoryMessageParams + + assert AgentV1SettingsAgentContextMessagesItemContentParams is ConversationHistoryMessageParams + assert ModuleContextContentParams is ConversationHistoryMessageParams + assert AgentContextContentParamsFromV1 is ConversationHistoryMessageParams + assert AgentContextContentParamsFromAgent is ConversationHistoryMessageParams + + assert AgentV1SettingsAgentContextMessagesItemFunctionCallsParams is FunctionCallHistoryMessageParams + assert ModuleContextFunctionCallsParams is FunctionCallHistoryMessageParams + assert AgentContextFunctionCallsParamsFromV1 is FunctionCallHistoryMessageParams + assert AgentContextFunctionCallsParamsFromAgent is FunctionCallHistoryMessageParams + + +def test_old_key_request_aliases_resolve_to_new_request_type() -> None: + assert CreateKeyV1RequestOneType is CreateKeyV1Request + assert ModuleCreateKeyV1RequestOne is CreateKeyV1Request + assert CreateKeyV1RequestOne is RootCreateKeyV1Request + + assert CreateKeyV1RequestOneParams is CreateKeyV1RequestParams + assert ModuleCreateKeyV1RequestOneParams is CreateKeyV1RequestParams + + +def test_old_agent_history_type_aliases_can_be_instantiated() -> None: + history_content = AgentV1HistoryContent(type="History", role="user", content="hello") + assert isinstance(history_content, ConversationHistoryMessage) + assert history_content.role == "user" + assert history_content.content == "hello" + + context_content = AgentV1SettingsAgentContextMessagesItemContent(type="History", role="assistant", content="hi") + assert isinstance(context_content, ConversationHistoryMessage) + assert context_content.role == "assistant" + assert context_content.content == "hi" + + function_call = { + "id": "fc_123", + "name": "lookup_weather", + "client_side": True, + "arguments": '{"city":"London"}', + "response": "sunny", + } + history_function_calls = AgentV1HistoryFunctionCalls(type="History", function_calls=[function_call]) + assert isinstance(history_function_calls, FunctionCallHistoryMessage) + assert history_function_calls.function_calls[0].name == "lookup_weather" + + context_function_calls = AgentV1SettingsAgentContextMessagesItemFunctionCalls( + type="History", function_calls=[function_call] + ) + assert isinstance(context_function_calls, FunctionCallHistoryMessage) + assert context_function_calls.function_calls[0].response == "sunny" diff --git a/tests/typecheck/compat_aliases.py b/tests/typecheck/compat_aliases.py new file mode 100644 index 00000000..a2db4059 --- /dev/null +++ b/tests/typecheck/compat_aliases.py @@ -0,0 +1,32 @@ +from typing import assert_type + +from deepgram.agent.v1.requests import ( + AgentV1HistoryContentParams, + AgentV1HistoryFunctionCallsParams, + ConversationHistoryMessageParams, + FunctionCallHistoryMessageParams, +) +from deepgram.requests import CreateKeyV1RequestOneParams, CreateKeyV1RequestParams + +create_key_request: CreateKeyV1RequestOneParams = {"key": "value"} +history_content: AgentV1HistoryContentParams = { + "type": "History", + "role": "user", + "content": "hello", +} +history_function_calls: AgentV1HistoryFunctionCallsParams = { + "type": "History", + "function_calls": [ + { + "id": "fc_123", + "name": "lookup_weather", + "client_side": True, + "arguments": '{"city":"London"}', + "response": "sunny", + } + ], +} + +assert_type(create_key_request, CreateKeyV1RequestParams) +assert_type(history_content, ConversationHistoryMessageParams) +assert_type(history_function_calls, FunctionCallHistoryMessageParams) diff --git a/tests/wire/test_manage_v1_projects_keys.py b/tests/wire/test_manage_v1_projects_keys.py index 7976bf7d..cf232369 100644 --- a/tests/wire/test_manage_v1_projects_keys.py +++ b/tests/wire/test_manage_v1_projects_keys.py @@ -1,5 +1,7 @@ from .conftest import get_client, verify_request_count +from deepgram.requests import CreateKeyV1RequestOneParams + def test_manage_v1_projects_keys_list_() -> None: """Test list endpoint with WireMock""" @@ -23,6 +25,18 @@ def test_manage_v1_projects_keys_create() -> None: verify_request_count(test_id, "POST", "/v1/projects/project_id/keys", None, 1) +def test_manage_v1_projects_keys_create_with_old_request_alias() -> None: + """Test create endpoint with the legacy request alias""" + test_id = "manage.v1.projects.keys.create.compat" + client = get_client(test_id) + request: CreateKeyV1RequestOneParams = {"key": "value"} + client.manage.v1.projects.keys.create( + project_id="project_id", + request=request, + ) + verify_request_count(test_id, "POST", "/v1/projects/project_id/keys", None, 1) + + def test_manage_v1_projects_keys_get() -> None: """Test get endpoint with WireMock""" test_id = "manage.v1.projects.keys.get.0" diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..43210fc9 --- /dev/null +++ b/uv.lock @@ -0,0 +1,479 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/9a/152096d4808df8e4268befa55fba462f440f14beab85e8ad9bf990516918/aiohttp-3.13.5.tar.gz", hash = "sha256:9d98cc980ecc96be6eb4c1994ce35d28d8b1f5e5208a23b421187d1209dbb7d1", size = 7858271, upload-time = "2026-03-31T22:01:03.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/ce/46572759afc859e867a5bc8ec3487315869013f59281ce61764f76d879de/aiohttp-3.13.5-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:eb4639f32fd4a9904ab8fb45bf3383ba71137f3d9d4ba25b3b3f3109977c5b8c", size = 745721, upload-time = "2026-03-31T21:58:50.229Z" }, + { url = "https://files.pythonhosted.org/packages/13/fe/8a2efd7626dbe6049b2ef8ace18ffda8a4dfcbe1bcff3ac30c0c7575c20b/aiohttp-3.13.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:7e5dc4311bd5ac493886c63cbf76ab579dbe4641268e7c74e48e774c74b6f2be", size = 497663, upload-time = "2026-03-31T21:58:52.232Z" }, + { url = "https://files.pythonhosted.org/packages/9b/91/cc8cc78a111826c54743d88651e1687008133c37e5ee615fee9b57990fac/aiohttp-3.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:756c3c304d394977519824449600adaf2be0ccee76d206ee339c5e76b70ded25", size = 499094, upload-time = "2026-03-31T21:58:54.566Z" }, + { url = "https://files.pythonhosted.org/packages/0a/33/a8362cb15cf16a3af7e86ed11962d5cd7d59b449202dc576cdc731310bde/aiohttp-3.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecc26751323224cf8186efcf7fbcbc30f4e1d8c7970659daf25ad995e4032a56", size = 1726701, upload-time = "2026-03-31T21:58:56.864Z" }, + { url = "https://files.pythonhosted.org/packages/45/0c/c091ac5c3a17114bd76cbf85d674650969ddf93387876cf67f754204bd77/aiohttp-3.13.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10a75acfcf794edf9d8db50e5a7ec5fc818b2a8d3f591ce93bc7b1210df016d2", size = 1683360, upload-time = "2026-03-31T21:58:59.072Z" }, + { url = "https://files.pythonhosted.org/packages/23/73/bcee1c2b79bc275e964d1446c55c54441a461938e70267c86afaae6fba27/aiohttp-3.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f7a18f258d124cd678c5fe072fe4432a4d5232b0657fca7c1847f599233c83a", size = 1773023, upload-time = "2026-03-31T21:59:01.776Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ef/720e639df03004fee2d869f771799d8c23046dec47d5b81e396c7cda583a/aiohttp-3.13.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df6104c009713d3a89621096f3e3e88cc323fd269dbd7c20afe18535094320be", size = 1853795, upload-time = "2026-03-31T21:59:04.568Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c9/989f4034fb46841208de7aeeac2c6d8300745ab4f28c42f629ba77c2d916/aiohttp-3.13.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:241a94f7de7c0c3b616627aaad530fe2cb620084a8b144d3be7b6ecfe95bae3b", size = 1730405, upload-time = "2026-03-31T21:59:07.221Z" }, + { url = "https://files.pythonhosted.org/packages/ce/75/ee1fd286ca7dc599d824b5651dad7b3be7ff8d9a7e7b3fe9820d9180f7db/aiohttp-3.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c974fb66180e58709b6fc402846f13791240d180b74de81d23913abe48e96d94", size = 1558082, upload-time = "2026-03-31T21:59:09.484Z" }, + { url = "https://files.pythonhosted.org/packages/c3/20/1e9e6650dfc436340116b7aa89ff8cb2bbdf0abc11dfaceaad8f74273a10/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6e27ea05d184afac78aabbac667450c75e54e35f62238d44463131bd3f96753d", size = 1692346, upload-time = "2026-03-31T21:59:12.068Z" }, + { url = "https://files.pythonhosted.org/packages/d8/40/8ebc6658d48ea630ac7903912fe0dd4e262f0e16825aa4c833c56c9f1f56/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a79a6d399cef33a11b6f004c67bb07741d91f2be01b8d712d52c75711b1e07c7", size = 1698891, upload-time = "2026-03-31T21:59:14.552Z" }, + { url = "https://files.pythonhosted.org/packages/d8/78/ea0ae5ec8ba7a5c10bdd6e318f1ba5e76fcde17db8275188772afc7917a4/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c632ce9c0b534fbe25b52c974515ed674937c5b99f549a92127c85f771a78772", size = 1742113, upload-time = "2026-03-31T21:59:17.068Z" }, + { url = "https://files.pythonhosted.org/packages/8a/66/9d308ed71e3f2491be1acb8769d96c6f0c47d92099f3bc9119cada27b357/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fceedde51fbd67ee2bcc8c0b33d0126cc8b51ef3bbde2f86662bd6d5a6f10ec5", size = 1553088, upload-time = "2026-03-31T21:59:19.541Z" }, + { url = "https://files.pythonhosted.org/packages/da/a6/6cc25ed8dfc6e00c90f5c6d126a98e2cf28957ad06fa1036bd34b6f24a2c/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f92995dfec9420bb69ae629abf422e516923ba79ba4403bc750d94fb4a6c68c1", size = 1757976, upload-time = "2026-03-31T21:59:22.311Z" }, + { url = "https://files.pythonhosted.org/packages/c1/2b/cce5b0ffe0de99c83e5e36d8f828e4161e415660a9f3e58339d07cce3006/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20ae0ff08b1f2c8788d6fb85afcb798654ae6ba0b747575f8562de738078457b", size = 1712444, upload-time = "2026-03-31T21:59:24.635Z" }, + { url = "https://files.pythonhosted.org/packages/6c/cf/9e1795b4160c58d29421eafd1a69c6ce351e2f7c8d3c6b7e4ca44aea1a5b/aiohttp-3.13.5-cp314-cp314-win32.whl", hash = "sha256:b20df693de16f42b2472a9c485e1c948ee55524786a0a34345511afdd22246f3", size = 438128, upload-time = "2026-03-31T21:59:27.291Z" }, + { url = "https://files.pythonhosted.org/packages/22/4d/eaedff67fc805aeba4ba746aec891b4b24cebb1a7d078084b6300f79d063/aiohttp-3.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:f85c6f327bf0b8c29da7d93b1cabb6363fb5e4e160a32fa241ed2dce21b73162", size = 464029, upload-time = "2026-03-31T21:59:29.429Z" }, + { url = "https://files.pythonhosted.org/packages/79/11/c27d9332ee20d68dd164dc12a6ecdef2e2e35ecc97ed6cf0d2442844624b/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:1efb06900858bb618ff5cee184ae2de5828896c448403d51fb633f09e109be0a", size = 778758, upload-time = "2026-03-31T21:59:31.547Z" }, + { url = "https://files.pythonhosted.org/packages/04/fb/377aead2e0a3ba5f09b7624f702a964bdf4f08b5b6728a9799830c80041e/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fee86b7c4bd29bdaf0d53d14739b08a106fdda809ca5fe032a15f52fae5fe254", size = 512883, upload-time = "2026-03-31T21:59:34.098Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a6/aa109a33671f7a5d3bd78b46da9d852797c5e665bfda7d6b373f56bff2ec/aiohttp-3.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:20058e23909b9e65f9da62b396b77dfa95965cbe840f8def6e572538b1d32e36", size = 516668, upload-time = "2026-03-31T21:59:36.497Z" }, + { url = "https://files.pythonhosted.org/packages/79/b3/ca078f9f2fa9563c36fb8ef89053ea2bb146d6f792c5104574d49d8acb63/aiohttp-3.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cf20a8d6868cb15a73cab329ffc07291ba8c22b1b88176026106ae39aa6df0f", size = 1883461, upload-time = "2026-03-31T21:59:38.723Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e3/a7ad633ca1ca497b852233a3cce6906a56c3225fb6d9217b5e5e60b7419d/aiohttp-3.13.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:330f5da04c987f1d5bdb8ae189137c77139f36bd1cb23779ca1a354a4b027800", size = 1747661, upload-time = "2026-03-31T21:59:41.187Z" }, + { url = "https://files.pythonhosted.org/packages/33/b9/cd6fe579bed34a906d3d783fe60f2fa297ef55b27bb4538438ee49d4dc41/aiohttp-3.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f1cbf0c7926d315c3c26c2da41fd2b5d2fe01ac0e157b78caefc51a782196cf", size = 1863800, upload-time = "2026-03-31T21:59:43.84Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3f/2c1e2f5144cefa889c8afd5cf431994c32f3b29da9961698ff4e3811b79a/aiohttp-3.13.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:53fc049ed6390d05423ba33103ded7281fe897cf97878f369a527070bd95795b", size = 1958382, upload-time = "2026-03-31T21:59:46.187Z" }, + { url = "https://files.pythonhosted.org/packages/66/1d/f31ec3f1013723b3babe3609e7f119c2c2fb6ef33da90061a705ef3e1bc8/aiohttp-3.13.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:898703aa2667e3c5ca4c54ca36cd73f58b7a38ef87a5606414799ebce4d3fd3a", size = 1803724, upload-time = "2026-03-31T21:59:48.656Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b4/57712dfc6f1542f067daa81eb61da282fab3e6f1966fca25db06c4fc62d5/aiohttp-3.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0494a01ca9584eea1e5fbd6d748e61ecff218c51b576ee1999c23db7066417d8", size = 1640027, upload-time = "2026-03-31T21:59:51.284Z" }, + { url = "https://files.pythonhosted.org/packages/25/3c/734c878fb43ec083d8e31bf029daae1beafeae582d1b35da234739e82ee7/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6cf81fe010b8c17b09495cbd15c1d35afbc8fb405c0c9cf4738e5ae3af1d65be", size = 1806644, upload-time = "2026-03-31T21:59:53.753Z" }, + { url = "https://files.pythonhosted.org/packages/20/a5/f671e5cbec1c21d044ff3078223f949748f3a7f86b14e34a365d74a5d21f/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:c564dd5f09ddc9d8f2c2d0a301cd30a79a2cc1b46dd1a73bef8f0038863d016b", size = 1791630, upload-time = "2026-03-31T21:59:56.239Z" }, + { url = "https://files.pythonhosted.org/packages/0b/63/fb8d0ad63a0b8a99be97deac8c04dacf0785721c158bdf23d679a87aa99e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2994be9f6e51046c4f864598fd9abeb4fba6e88f0b2152422c9666dcd4aea9c6", size = 1809403, upload-time = "2026-03-31T21:59:59.103Z" }, + { url = "https://files.pythonhosted.org/packages/59/0c/bfed7f30662fcf12206481c2aac57dedee43fe1c49275e85b3a1e1742294/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:157826e2fa245d2ef46c83ea8a5faf77ca19355d278d425c29fda0beb3318037", size = 1634924, upload-time = "2026-03-31T22:00:02.116Z" }, + { url = "https://files.pythonhosted.org/packages/17/d6/fd518d668a09fd5a3319ae5e984d4d80b9a4b3df4e21c52f02251ef5a32e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a8aca50daa9493e9e13c0f566201a9006f080e7c50e5e90d0b06f53146a54500", size = 1836119, upload-time = "2026-03-31T22:00:04.756Z" }, + { url = "https://files.pythonhosted.org/packages/78/b7/15fb7a9d52e112a25b621c67b69c167805cb1f2ab8f1708a5c490d1b52fe/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3b13560160d07e047a93f23aaa30718606493036253d5430887514715b67c9d9", size = 1772072, upload-time = "2026-03-31T22:00:07.494Z" }, + { url = "https://files.pythonhosted.org/packages/7e/df/57ba7f0c4a553fc2bd8b6321df236870ec6fd64a2a473a8a13d4f733214e/aiohttp-3.13.5-cp314-cp314t-win32.whl", hash = "sha256:9a0f4474b6ea6818b41f82172d799e4b3d29e22c2c520ce4357856fced9af2f8", size = 471819, upload-time = "2026-03-31T22:00:10.277Z" }, + { url = "https://files.pythonhosted.org/packages/62/29/2f8418269e46454a26171bfdd6a055d74febf32234e474930f2f60a17145/aiohttp-3.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:18a2f6c1182c51baa1d28d68fea51513cb2a76612f038853c0ad3c145423d3d9", size = 505441, upload-time = "2026-03-31T22:00:12.791Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "certifi" +version = "2026.4.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, +] + +[[package]] +name = "deepgram-sdk" +source = { editable = "." } +dependencies = [ + { name = "httpx" }, + { name = "pydantic" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] + +[package.optional-dependencies] +aiohttp = [ + { name = "aiohttp" }, + { name = "httpx-aiohttp" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", marker = "python_full_version >= '3.9' and extra == 'aiohttp'", specifier = ">=3.13.4,<4" }, + { name = "httpx", specifier = ">=0.21.2" }, + { name = "httpx-aiohttp", marker = "python_full_version >= '3.9' and extra == 'aiohttp'", specifier = "==0.1.8" }, + { name = "pydantic", specifier = ">=1.9.2" }, + { name = "pydantic-core", specifier = ">=2.18.2,<2.44.0" }, + { name = "typing-extensions", specifier = ">=4.0.0" }, + { name = "websockets", specifier = ">=12.0" }, +] +provides-extras = ["aiohttp"] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "httpx-aiohttp" +version = "0.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/19/ae2d2bf1f57fdd23c8ad83675599fb5c407fa13bc20e90f00cffa4dea3aa/httpx_aiohttp-0.1.8.tar.gz", hash = "sha256:756c5e74cdb568c3248ba63fe82bfe8bbe64b928728720f7eaac64b3cf46f308", size = 25401, upload-time = "2025-07-04T10:40:32.329Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/7a/514c484b88cc4ebbcd2e27e92b86019c0c5bb920582f5fbb10b7e6c78574/httpx_aiohttp-0.1.8-py3-none-any.whl", hash = "sha256:b7bd958d1331f3759a38a0ba22ad29832cb63ca69498c17735228055bf78fa7e", size = 6180, upload-time = "2025-07-04T10:40:31.522Z" }, +] + +[[package]] +name = "idna" +version = "3.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/cc/db74228a8be41884a567e88a62fd589a913708fcf180d029898c17a9a371/multidict-6.7.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8f333ec9c5eb1b7105e3b84b53141e66ca05a19a605368c55450b6ba208cb9ee", size = 75190, upload-time = "2026-01-26T02:45:10.651Z" }, + { url = "https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2", size = 44486, upload-time = "2026-01-26T02:45:11.938Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1", size = 43219, upload-time = "2026-01-26T02:45:14.346Z" }, + { url = "https://files.pythonhosted.org/packages/24/bb/2c0c2287963f4259c85e8bcbba9182ced8d7fca65c780c38e99e61629d11/multidict-6.7.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1e3a8bb24342a8201d178c3b4984c26ba81a577c80d4d525727427460a50c22d", size = 245132, upload-time = "2026-01-26T02:45:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f9/44d4b3064c65079d2467888794dea218d1601898ac50222ab8a9a8094460/multidict-6.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97231140a50f5d447d3164f994b86a0bed7cd016e2682f8650d6a9158e14fd31", size = 252420, upload-time = "2026-01-26T02:45:17.293Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/78f7275e73fa17b24c9a51b0bd9d73ba64bb32d0ed51b02a746eb876abe7/multidict-6.7.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b10359683bd8806a200fd2909e7c8ca3a7b24ec1d8132e483d58e791d881048", size = 233510, upload-time = "2026-01-26T02:45:19.356Z" }, + { url = "https://files.pythonhosted.org/packages/4b/25/8167187f62ae3cbd52da7893f58cb036b47ea3fb67138787c76800158982/multidict-6.7.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:283ddac99f7ac25a4acadbf004cb5ae34480bbeb063520f70ce397b281859362", size = 264094, upload-time = "2026-01-26T02:45:20.834Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e7/69a3a83b7b030cf283fb06ce074a05a02322359783424d7edf0f15fe5022/multidict-6.7.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:538cec1e18c067d0e6103aa9a74f9e832904c957adc260e61cd9d8cf0c3b3d37", size = 260786, upload-time = "2026-01-26T02:45:22.818Z" }, + { url = "https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709", size = 248483, upload-time = "2026-01-26T02:45:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/48/5a/d5a99e3acbca0e29c5d9cba8f92ceb15dce78bab963b308ae692981e3a5d/multidict-6.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa263a02f4f2dd2d11a7b1bb4362aa7cb1049f84a9235d31adf63f30143469a0", size = 248403, upload-time = "2026-01-26T02:45:25.982Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/e58cd31f6c7d5102f2a4bf89f96b9cf7e00b6c6f3d04ecc44417c00a5a3c/multidict-6.7.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2e1425e2f99ec5bd36c15a01b690a1a2456209c5deed58f95469ffb46039ccbb", size = 240315, upload-time = "2026-01-26T02:45:27.487Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/1cd210229559cb90b6786c30676bb0c58249ff42f942765f88793b41fdce/multidict-6.7.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:497394b3239fc6f0e13a78a3e1b61296e72bf1c5f94b4c4eb80b265c37a131cd", size = 245528, upload-time = "2026-01-26T02:45:28.991Z" }, + { url = "https://files.pythonhosted.org/packages/64/f2/6e1107d226278c876c783056b7db43d800bb64c6131cec9c8dfb6903698e/multidict-6.7.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:233b398c29d3f1b9676b4b6f75c518a06fcb2ea0b925119fb2c1bc35c05e1601", size = 258784, upload-time = "2026-01-26T02:45:30.503Z" }, + { url = "https://files.pythonhosted.org/packages/4d/c1/11f664f14d525e4a1b5327a82d4de61a1db604ab34c6603bb3c2cc63ad34/multidict-6.7.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:93b1818e4a6e0930454f0f2af7dfce69307ca03cdcfb3739bf4d91241967b6c1", size = 251980, upload-time = "2026-01-26T02:45:32.603Z" }, + { url = "https://files.pythonhosted.org/packages/e1/9f/75a9ac888121d0c5bbd4ecf4eead45668b1766f6baabfb3b7f66a410e231/multidict-6.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f33dc2a3abe9249ea5d8360f969ec7f4142e7ac45ee7014d8f8d5acddf178b7b", size = 243602, upload-time = "2026-01-26T02:45:34.043Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e7/50bf7b004cc8525d80dbbbedfdc7aed3e4c323810890be4413e589074032/multidict-6.7.1-cp314-cp314-win32.whl", hash = "sha256:3ab8b9d8b75aef9df299595d5388b14530839f6422333357af1339443cff777d", size = 40930, upload-time = "2026-01-26T02:45:36.278Z" }, + { url = "https://files.pythonhosted.org/packages/e0/bf/52f25716bbe93745595800f36fb17b73711f14da59ed0bb2eba141bc9f0f/multidict-6.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:5e01429a929600e7dab7b166062d9bb54a5eed752384c7384c968c2afab8f50f", size = 45074, upload-time = "2026-01-26T02:45:37.546Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/22803b03285fa3a525f48217963da3a65ae40f6a1b6f6cf2768879e208f9/multidict-6.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:4885cb0e817aef5d00a2e8451d4665c1808378dc27c2705f1bf4ef8505c0d2e5", size = 42471, upload-time = "2026-01-26T02:45:38.889Z" }, + { url = "https://files.pythonhosted.org/packages/e0/6d/f9293baa6146ba9507e360ea0292b6422b016907c393e2f63fc40ab7b7b5/multidict-6.7.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0458c978acd8e6ea53c81eefaddbbee9c6c5e591f41b3f5e8e194780fe026581", size = 82401, upload-time = "2026-01-26T02:45:40.254Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/53b5494738d83558d87c3c71a486504d8373421c3e0dbb6d0db48ad42ee0/multidict-6.7.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c0abd12629b0af3cf590982c0b413b1e7395cd4ec026f30986818ab95bfaa94a", size = 48143, upload-time = "2026-01-26T02:45:41.635Z" }, + { url = "https://files.pythonhosted.org/packages/37/e8/5284c53310dcdc99ce5d66563f6e5773531a9b9fe9ec7a615e9bc306b05f/multidict-6.7.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:14525a5f61d7d0c94b368a42cff4c9a4e7ba2d52e2672a7b23d84dc86fb02b0c", size = 46507, upload-time = "2026-01-26T02:45:42.99Z" }, + { url = "https://files.pythonhosted.org/packages/e4/fc/6800d0e5b3875568b4083ecf5f310dcf91d86d52573160834fb4bfcf5e4f/multidict-6.7.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17307b22c217b4cf05033dabefe68255a534d637c6c9b0cc8382718f87be4262", size = 239358, upload-time = "2026-01-26T02:45:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/4ad0973179361cdf3a113905e6e088173198349131be2b390f9fa4da5fc6/multidict-6.7.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a7e590ff876a3eaf1c02a4dfe0724b6e69a9e9de6d8f556816f29c496046e59", size = 246884, upload-time = "2026-01-26T02:45:47.167Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9c/095bb28b5da139bd41fb9a5d5caff412584f377914bd8787c2aa98717130/multidict-6.7.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5fa6a95dfee63893d80a34758cd0e0c118a30b8dcb46372bf75106c591b77889", size = 225878, upload-time = "2026-01-26T02:45:48.698Z" }, + { url = "https://files.pythonhosted.org/packages/07/d0/c0a72000243756e8f5a277b6b514fa005f2c73d481b7d9e47cd4568aa2e4/multidict-6.7.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a0543217a6a017692aa6ae5cc39adb75e587af0f3a82288b1492eb73dd6cc2a4", size = 253542, upload-time = "2026-01-26T02:45:50.164Z" }, + { url = "https://files.pythonhosted.org/packages/c0/6b/f69da15289e384ecf2a68837ec8b5ad8c33e973aa18b266f50fe55f24b8c/multidict-6.7.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f99fe611c312b3c1c0ace793f92464d8cd263cc3b26b5721950d977b006b6c4d", size = 252403, upload-time = "2026-01-26T02:45:51.779Z" }, + { url = "https://files.pythonhosted.org/packages/a2/76/b9669547afa5a1a25cd93eaca91c0da1c095b06b6d2d8ec25b713588d3a1/multidict-6.7.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9004d8386d133b7e6135679424c91b0b854d2d164af6ea3f289f8f2761064609", size = 244889, upload-time = "2026-01-26T02:45:53.27Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a9/a50d2669e506dad33cfc45b5d574a205587b7b8a5f426f2fbb2e90882588/multidict-6.7.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e628ef0e6859ffd8273c69412a2465c4be4a9517d07261b33334b5ec6f3c7489", size = 241982, upload-time = "2026-01-26T02:45:54.919Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bb/1609558ad8b456b4827d3c5a5b775c93b87878fd3117ed3db3423dfbce1b/multidict-6.7.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:841189848ba629c3552035a6a7f5bf3b02eb304e9fea7492ca220a8eda6b0e5c", size = 232415, upload-time = "2026-01-26T02:45:56.981Z" }, + { url = "https://files.pythonhosted.org/packages/d8/59/6f61039d2aa9261871e03ab9dc058a550d240f25859b05b67fd70f80d4b3/multidict-6.7.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce1bbd7d780bb5a0da032e095c951f7014d6b0a205f8318308140f1a6aba159e", size = 240337, upload-time = "2026-01-26T02:45:58.698Z" }, + { url = "https://files.pythonhosted.org/packages/a1/29/fdc6a43c203890dc2ae9249971ecd0c41deaedfe00d25cb6564b2edd99eb/multidict-6.7.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b26684587228afed0d50cf804cc71062cc9c1cdf55051c4c6345d372947b268c", size = 248788, upload-time = "2026-01-26T02:46:00.862Z" }, + { url = "https://files.pythonhosted.org/packages/a9/14/a153a06101323e4cf086ecee3faadba52ff71633d471f9685c42e3736163/multidict-6.7.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9f9af11306994335398293f9958071019e3ab95e9a707dc1383a35613f6abcb9", size = 242842, upload-time = "2026-01-26T02:46:02.824Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/604ae839e64a4a6efc80db94465348d3b328ee955e37acb24badbcd24d83/multidict-6.7.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b4938326284c4f1224178a560987b6cf8b4d38458b113d9b8c1db1a836e640a2", size = 240237, upload-time = "2026-01-26T02:46:05.898Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/c3a5187bf66f6fb546ff4ab8fb5a077cbdd832d7b1908d4365c7f74a1917/multidict-6.7.1-cp314-cp314t-win32.whl", hash = "sha256:98655c737850c064a65e006a3df7c997cd3b220be4ec8fe26215760b9697d4d7", size = 48008, upload-time = "2026-01-26T02:46:07.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f7/addf1087b860ac60e6f382240f64fb99f8bfb532bb06f7c542b83c29ca61/multidict-6.7.1-cp314-cp314t-win_amd64.whl", hash = "sha256:497bde6223c212ba11d462853cfa4f0ae6ef97465033e7dc9940cdb3ab5b48e5", size = 53542, upload-time = "2026-01-26T02:46:08.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/81/4629d0aa32302ef7b2ec65c75a728cc5ff4fa410c50096174c1632e70b3e/multidict-6.7.1-cp314-cp314t-win_arm64.whl", hash = "sha256:2bbd113e0d4af5db41d5ebfe9ccaff89de2120578164f86a5d17d5a576d1e5b2", size = 44719, upload-time = "2026-01-26T02:46:11.146Z" }, + { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "websockets" +version = "16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" }, + { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" }, + { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" }, + { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" }, + { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" }, + { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" }, + { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" }, + { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" }, + { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, +] + +[[package]] +name = "yarl" +version = "1.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, + { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, + { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, + { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, + { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, + { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, + { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, + { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, + { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, + { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, + { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, + { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, + { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, + { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, + { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, + { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, + { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, + { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, + { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, + { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, + { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, + { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, + { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, + { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, + { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, + { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, + { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, + { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, + { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +] From bd3e4e0c409470129ec137e84fa799935ce59978 Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Fri, 1 May 2026 11:02:45 +0100 Subject: [PATCH 6/6] fix: update examples for regenerated SDK behavior Align the Listen V2, streaming TTS, voice agent, and management project examples with the current SDK/runtime behavior after regen, including safer websocket flows and updated project update handling. --- .../14-transcription-live-websocket-v2.py | 5 +- examples/24-text-builder-streaming.py | 43 ++++++++++----- examples/30-voice-agent.py | 55 +++++++++++-------- examples/50-management-projects.py | 10 +++- 4 files changed, 70 insertions(+), 43 deletions(-) diff --git a/examples/14-transcription-live-websocket-v2.py b/examples/14-transcription-live-websocket-v2.py index c60a50ab..a0fe09bc 100644 --- a/examples/14-transcription-live-websocket-v2.py +++ b/examples/14-transcription-live-websocket-v2.py @@ -3,6 +3,9 @@ This example shows how to use Listen V2 for advanced conversational speech recognition with contextual turn detection. + +It streams the bundled WAV fixture directly, so the example lets Deepgram infer the +audio format from the container instead of forcing raw linear16 settings. """ import os @@ -31,8 +34,6 @@ try: with client.listen.v2.connect( model="flux-general-en", - encoding="linear16", - sample_rate="16000", ) as connection: def on_message(message: ListenV2SocketClientResponse) -> None: diff --git a/examples/24-text-builder-streaming.py b/examples/24-text-builder-streaming.py index 3b49748e..b3608a00 100644 --- a/examples/24-text-builder-streaming.py +++ b/examples/24-text-builder-streaming.py @@ -4,15 +4,20 @@ This example demonstrates using TextBuilder with streaming text-to-speech over WebSocket for real-time audio generation. + +The streaming API path shown here focuses on pronunciation controls. Inline +pause tokens are omitted because the WebSocket endpoint may reject them with +DATA-0002 policy violations. """ import os +import threading from typing import Union from deepgram import DeepgramClient from deepgram.helpers import TextBuilder from deepgram.core.events import EventType -from deepgram.speak.v1.types import SpeakV1Close, SpeakV1Flush, SpeakV1Text +from deepgram.speak.v1.types import SpeakV1Text SpeakV1SocketClientResponse = Union[str, bytes] @@ -30,7 +35,6 @@ def example_streaming_with_textbuilder(): .text(" twice daily with ") .pronunciation("dupilumab", "duːˈpɪljuːmæb") .text(" injections.") - .pause(500) .text(" Do not exceed prescribed dosage.") .build() ) @@ -46,8 +50,9 @@ def example_streaming_with_textbuilder(): try: with client.speak.v1.connect( - model="aura-asteria-en", encoding="linear16", sample_rate=24000 + model="aura-2-asteria-en", encoding="linear16", sample_rate=24000 ) as connection: + closed_event = threading.Event() def on_message(message: SpeakV1SocketClientResponse) -> None: if isinstance(message, bytes): @@ -58,10 +63,12 @@ def on_message(message: SpeakV1SocketClientResponse) -> None: else: msg_type = getattr(message, "type", "Unknown") print(f"Received {msg_type} event") + if msg_type == "Flushed": + connection.send_close() connection.on(EventType.OPEN, lambda _: print("✓ Connection opened")) connection.on(EventType.MESSAGE, on_message) - connection.on(EventType.CLOSE, lambda _: print("✓ Connection closed")) + connection.on(EventType.CLOSE, lambda _: (print("✓ Connection closed"), closed_event.set())) connection.on(EventType.ERROR, lambda error: print(f"✗ Error: {error}")) # Send the TextBuilder-generated text @@ -70,11 +77,9 @@ def on_message(message: SpeakV1SocketClientResponse) -> None: # Flush to ensure all text is processed connection.send_flush() - # Close the connection when done - connection.send_close() - - # Start listening - this blocks until the connection closes - connection.start_listening() + listener = threading.Thread(target=connection.start_listening, daemon=True) + listener.start() + closed_event.wait(30) print("\n✓ Audio saved to streaming_output.raw") print(" Convert to WAV: ffmpeg -f s16le -ar 24000 -ac 1 -i streaming_output.raw output.wav") @@ -118,19 +123,24 @@ def example_multiple_messages(): try: with client.speak.v1.connect( - model="aura-asteria-en", encoding="linear16", sample_rate=24000 + model="aura-2-asteria-en", encoding="linear16", sample_rate=24000 ) as connection: audio_chunks = [] + closed_event = threading.Event() def on_message(message: SpeakV1SocketClientResponse) -> None: if isinstance(message, bytes): audio_chunks.append(message) print(f"Received {len(message)} bytes") + else: + msg_type = getattr(message, "type", "Unknown") + if msg_type == "Flushed": + connection.send_close() connection.on(EventType.OPEN, lambda _: print("✓ Connection opened")) connection.on(EventType.MESSAGE, on_message) - connection.on(EventType.CLOSE, lambda _: print("✓ Connection closed")) + connection.on(EventType.CLOSE, lambda _: (print("✓ Connection closed"), closed_event.set())) # Send multiple messages for i, text in enumerate([intro, instruction1, instruction2, closing], 1): @@ -138,9 +148,10 @@ def on_message(message: SpeakV1SocketClientResponse) -> None: connection.send_text(SpeakV1Text(text=text)) connection.send_flush() - connection.send_close() - connection.start_listening() + listener = threading.Thread(target=connection.start_listening, daemon=True) + listener.start() + closed_event.wait(30) # Save all audio with open("streaming_multi.raw", "wb") as f: @@ -155,6 +166,11 @@ def on_message(message: SpeakV1SocketClientResponse) -> None: def main(): """Run all streaming examples""" + if os.path.exists("streaming_output.raw"): + os.remove("streaming_output.raw") + if os.path.exists("streaming_multi.raw"): + os.remove("streaming_multi.raw") + example_streaming_with_textbuilder() example_multiple_messages() @@ -165,4 +181,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/examples/30-voice-agent.py b/examples/30-voice-agent.py index f88188a7..75f57cfb 100644 --- a/examples/30-voice-agent.py +++ b/examples/30-voice-agent.py @@ -2,10 +2,10 @@ Example: Voice Agent (Agent V1) This example shows how to set up a voice agent that can listen, think, and speak. -It streams a pre-recorded audio file to simulate user speech. +To keep the example deterministic, it injects a user message after the settings are +applied and then prints the agent's text and audio responses. """ -import os import threading import time from typing import Union @@ -16,6 +16,7 @@ from deepgram import DeepgramClient from deepgram.agent.v1.types import ( + AgentV1InjectUserMessage, AgentV1Settings, AgentV1SettingsAgent, AgentV1SettingsAgentListen, @@ -30,13 +31,15 @@ from deepgram.types.think_settings_v1provider import ThinkSettingsV1Provider_OpenAi AgentV1SocketClientResponse = Union[str, bytes] +USER_MESSAGE = "What does the first all-female spacewalk symbolize?" client = DeepgramClient() -audio_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures", "audio.wav") - try: with client.agent.v1.connect() as agent: + settings_applied_event = threading.Event() + assistant_response_event = threading.Event() + # Configure the agent settings settings = AgentV1Settings( audio=AgentV1SettingsAudio( @@ -69,18 +72,20 @@ ), ) - print("Sending agent settings...") - agent.send_settings(settings) - def on_message(message: AgentV1SocketClientResponse) -> None: if isinstance(message, bytes): print(f"Received agent audio ({len(message)} bytes)") else: msg_type = getattr(message, "type", "Unknown") - if msg_type == "ConversationText": + if msg_type == "SettingsApplied": + print("Received SettingsApplied event") + settings_applied_event.set() + elif msg_type == "ConversationText": role = getattr(message, "role", "unknown") content = getattr(message, "content", "") print(f"[{role}] {content}") + if role == "assistant": + assistant_response_event.set() elif msg_type == "UserStartedSpeaking": print(">> User started speaking") elif msg_type == "AgentThinking": @@ -89,6 +94,11 @@ def on_message(message: AgentV1SocketClientResponse) -> None: print(">> Agent started speaking") elif msg_type == "AgentAudioDone": print(">> Agent finished speaking") + elif msg_type == "Error": + print( + f">> Agent error: {getattr(message, 'code', 'unknown')} - " + f"{getattr(message, 'description', 'unknown error')}" + ) else: print(f"Received {msg_type} event") @@ -97,26 +107,23 @@ def on_message(message: AgentV1SocketClientResponse) -> None: agent.on(EventType.CLOSE, lambda _: print("Connection closed")) agent.on(EventType.ERROR, lambda error: print(f"Error: {error}")) - # Stream audio in a background thread - def send_audio(): - with open(audio_path, "rb") as f: - audio_data = f.read() + listener = threading.Thread(target=agent.start_listening, daemon=True) + listener.start() + + print("Sending agent settings...") + agent.send_settings(settings) - chunk_size = 8192 - for i in range(0, len(audio_data), chunk_size): - chunk = audio_data[i : i + chunk_size] - if chunk: - agent.send_media(chunk) - time.sleep(0.01) + if not settings_applied_event.wait(10): + raise TimeoutError("Timed out waiting for agent settings to apply") - print("Finished streaming audio, waiting for agent response...") - time.sleep(15) + print(f"Sending injected user message: {USER_MESSAGE}") + agent.send_inject_user_message(AgentV1InjectUserMessage(content=USER_MESSAGE)) - sender = threading.Thread(target=send_audio, daemon=True) - sender.start() + if not assistant_response_event.wait(30): + raise TimeoutError("Timed out waiting for the agent to respond") - # Start listening - blocks until connection closes - agent.start_listening() + # Give the final audio callbacks a moment to flush before exiting the context. + time.sleep(2) except Exception as e: print(f"Error: {e}") diff --git a/examples/50-management-projects.py b/examples/50-management-projects.py index 43a39fb9..9500074f 100644 --- a/examples/50-management-projects.py +++ b/examples/50-management-projects.py @@ -27,10 +27,14 @@ project = client.manage.v1.projects.get(project_id=project_id) print(f"Project name: {project.name}") - # Update project name + # Update the project using the current name so the example exercises the + # update endpoint without unexpectedly renaming a live project. print("\nUpdating project name...") - updated = client.manage.v1.projects.update(project_id=project_id, name="Updated Project Name") - print(f"Updated project name: {updated.name}") + updated = client.manage.v1.projects.update(project_id=project_id, name=project.name) + print(f"Update response: {updated.message}") + + refreshed_project = client.manage.v1.projects.get(project_id=project_id) + print(f"Verified project name: {refreshed_project.name}") # Note: Delete and leave operations are commented out for safety # Delete a project: