Skip to content

Commit e8cf41c

Browse files
committed
chore: re-apply manual patches after regen
This covers: re-applied socket client patches (construct_type keyword args, broad exception catch, optional send_ params, _sanitize_numeric_types), removed .bak files, restored .fernignore, dropped type file freezes (generator now correct), fixed wiremock date format.
1 parent 37c9e23 commit e8cf41c

13 files changed

Lines changed: 93 additions & 1218 deletions

.fernignore

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,10 @@ src/deepgram/client.py
1111
# - optional message param on control send_ methods (send_keep_alive, send_close_stream, etc.)
1212
# so users don't need to instantiate the type themselves for no-payload control messages
1313
# [temporarily frozen — generator bugs in construct_type call convention and exception handling]
14-
src/deepgram/agent/v1/socket_client.py.bak
15-
src/deepgram/listen/v1/socket_client.py.bak
16-
src/deepgram/listen/v2/socket_client.py.bak
17-
src/deepgram/speak/v1/socket_client.py.bak
18-
19-
# Type files with manual int type corrections (Fern generates float for speaker/channel/num_words)
20-
# [temporarily frozen — waiting on internal-api-specs#205]
21-
src/deepgram/types/listen_v1response_results_utterances_item.py.bak
22-
src/deepgram/types/listen_v1response_results_utterances_item_words_item.py.bak
23-
src/deepgram/types/listen_v1response_results_channels_item_alternatives_item_paragraphs_paragraphs_item.py.bak
14+
src/deepgram/agent/v1/socket_client.py
15+
src/deepgram/listen/v1/socket_client.py
16+
src/deepgram/listen/v2/socket_client.py
17+
src/deepgram/speak/v1/socket_client.py
2418

2519
# Hand-written custom tests
2620
tests/custom/test_text_builder.py

src/deepgram/agent/v1/socket_client.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
import json
44
import logging
55
import typing
6-
from json.decoder import JSONDecodeError
7-
8-
import websockets
96
import websockets.sync.connection as websockets_sync_connection
107
from ...core.events import EventEmitterMixin, EventType
118
from ...core.unchecked_base_model import construct_type
@@ -39,6 +36,28 @@
3936
from websockets import WebSocketClientProtocol # type: ignore
4037

4138
_logger = logging.getLogger(__name__)
39+
40+
41+
def _sanitize_numeric_types(obj: typing.Any) -> typing.Any:
42+
"""
43+
Recursively convert float values that are whole numbers to int.
44+
45+
Workaround for Fern-generated models that type integer API fields
46+
(like sample_rate) as float, causing JSON serialization to produce
47+
values like 44100.0 instead of 44100. The Deepgram API rejects
48+
float representations of integer fields.
49+
50+
See: https://github.com/deepgram/internal-api-specs/issues/205
51+
"""
52+
if isinstance(obj, dict):
53+
return {k: _sanitize_numeric_types(v) for k, v in obj.items()}
54+
elif isinstance(obj, list):
55+
return [_sanitize_numeric_types(item) for item in obj]
56+
elif isinstance(obj, float) and obj.is_integer():
57+
return int(obj)
58+
return obj
59+
60+
4261
V1SocketClientResponse = typing.Union[
4362
AgentV1ReceiveFunctionCallResponse,
4463
AgentV1PromptUpdated,
@@ -70,7 +89,7 @@ async def __aiter__(self):
7089
yield message
7190
else:
7291
try:
73-
yield construct_type(V1SocketClientResponse, json.loads(message)) # type: ignore
92+
yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore
7493
except Exception:
7594
_logger.warning(
7695
"Skipping unknown WebSocket message; update your SDK version to support new message types."
@@ -95,14 +114,14 @@ async def start_listening(self):
95114
else:
96115
json_data = json.loads(raw_message)
97116
try:
98-
parsed = construct_type(V1SocketClientResponse, json_data) # type: ignore
117+
parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore
99118
except Exception:
100119
_logger.warning(
101120
"Skipping unknown WebSocket message; update your SDK version to support new message types."
102121
)
103122
continue
104123
await self._emit_async(EventType.MESSAGE, parsed)
105-
except (websockets.WebSocketException, JSONDecodeError) as exc:
124+
except Exception as exc:
106125
await self._emit_async(EventType.ERROR, exc)
107126
finally:
108127
await self._emit_async(EventType.CLOSE, None)
@@ -142,12 +161,12 @@ async def send_function_call_response(self, message: AgentV1SendFunctionCallResp
142161
"""
143162
await self._send_model(message)
144163

145-
async def send_keep_alive(self, message: AgentV1KeepAlive) -> None:
164+
async def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None:
146165
"""
147166
Send a message to the websocket connection.
148167
The message will be sent as a AgentV1KeepAlive.
149168
"""
150-
await self._send_model(message)
169+
await self._send_model(message or AgentV1KeepAlive(type="KeepAlive"))
151170

152171
async def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None:
153172
"""
@@ -179,7 +198,7 @@ async def recv(self) -> V1SocketClientResponse:
179198
return data # type: ignore
180199
json_data = json.loads(data)
181200
try:
182-
return construct_type(V1SocketClientResponse, json_data) # type: ignore
201+
return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore
183202
except Exception:
184203
_logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.")
185204
return json_data # type: ignore
@@ -196,7 +215,7 @@ async def _send_model(self, data: typing.Any) -> None:
196215
"""
197216
Send a Pydantic model to the websocket connection.
198217
"""
199-
await self._send(data.dict())
218+
await self._send(_sanitize_numeric_types(data.dict()))
200219

201220

202221
class V1SocketClient(EventEmitterMixin):
@@ -210,7 +229,7 @@ def __iter__(self):
210229
yield message
211230
else:
212231
try:
213-
yield construct_type(V1SocketClientResponse, json.loads(message)) # type: ignore
232+
yield construct_type(type_=V1SocketClientResponse, object_=json.loads(message)) # type: ignore
214233
except Exception:
215234
_logger.warning(
216235
"Skipping unknown WebSocket message; update your SDK version to support new message types."
@@ -235,14 +254,14 @@ def start_listening(self):
235254
else:
236255
json_data = json.loads(raw_message)
237256
try:
238-
parsed = construct_type(V1SocketClientResponse, json_data) # type: ignore
257+
parsed = construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore
239258
except Exception:
240259
_logger.warning(
241260
"Skipping unknown WebSocket message; update your SDK version to support new message types."
242261
)
243262
continue
244263
self._emit(EventType.MESSAGE, parsed)
245-
except (websockets.WebSocketException, JSONDecodeError) as exc:
264+
except Exception as exc:
246265
self._emit(EventType.ERROR, exc)
247266
finally:
248267
self._emit(EventType.CLOSE, None)
@@ -282,12 +301,12 @@ def send_function_call_response(self, message: AgentV1SendFunctionCallResponse)
282301
"""
283302
self._send_model(message)
284303

285-
def send_keep_alive(self, message: AgentV1KeepAlive) -> None:
304+
def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None:
286305
"""
287306
Send a message to the websocket connection.
288307
The message will be sent as a AgentV1KeepAlive.
289308
"""
290-
self._send_model(message)
309+
self._send_model(message or AgentV1KeepAlive(type="KeepAlive"))
291310

292311
def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None:
293312
"""
@@ -319,7 +338,7 @@ def recv(self) -> V1SocketClientResponse:
319338
return data # type: ignore
320339
json_data = json.loads(data)
321340
try:
322-
return construct_type(V1SocketClientResponse, json_data) # type: ignore
341+
return construct_type(type_=V1SocketClientResponse, object_=json_data) # type: ignore
323342
except Exception:
324343
_logger.warning("Skipping unknown WebSocket message; update your SDK version to support new message types.")
325344
return json_data # type: ignore
@@ -336,4 +355,4 @@ def _send_model(self, data: typing.Any) -> None:
336355
"""
337356
Send a Pydantic model to the websocket connection.
338357
"""
339-
self._send(data.dict())
358+
self._send(_sanitize_numeric_types(data.dict()))

0 commit comments

Comments
 (0)