Skip to content

Commit 2595d9f

Browse files
Merge pull request #437 from dvonthenen/httpx-stream-func
Implements Raw Byte Stream Access for Speak REST
2 parents 8939e59 + dade804 commit 2595d9f

File tree

10 files changed

+581
-56
lines changed

10 files changed

+581
-56
lines changed

deepgram/clients/abstract_async_client.py

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,29 @@ async def get(
6060
**kwargs,
6161
)
6262

63-
async def post_file(
63+
async def post_raw(
64+
self,
65+
url: str,
66+
options: Optional[Dict] = None,
67+
addons: Optional[Dict] = None,
68+
headers: Optional[Dict] = None,
69+
timeout: Optional[httpx.Timeout] = None,
70+
**kwargs,
71+
) -> httpx.Response:
72+
"""
73+
Make a POST request to the specified URL and return response in raw bytes.
74+
"""
75+
return await self._handle_request_raw(
76+
"POST",
77+
url,
78+
params=options,
79+
addons=addons,
80+
headers=headers,
81+
timeout=timeout,
82+
**kwargs,
83+
)
84+
85+
async def post_memory(
6486
self,
6587
url: str,
6688
file_result: List,
@@ -69,11 +91,11 @@ async def post_file(
6991
headers: Optional[Dict] = None,
7092
timeout: Optional[httpx.Timeout] = None,
7193
**kwargs,
72-
) -> Dict[str, Union[str, object]]:
94+
) -> Dict[str, Union[str, io.BytesIO]]:
7395
"""
74-
Make a POST request to the specified URL and return a file response.
96+
Make a POST request to the specified URL and return response in memory.
7597
"""
76-
return await self._handle_request_file(
98+
return await self._handle_request_memory(
7799
"POST",
78100
url,
79101
file_result=file_result,
@@ -224,7 +246,7 @@ async def _handle_request(
224246
# pylint: enable-msg=too-many-locals,too-many-branches,too-many-locals
225247

226248
# pylint: disable-msg=too-many-locals,too-many-branches
227-
async def _handle_request_file(
249+
async def _handle_request_memory(
228250
self,
229251
method: str,
230252
url: str,
@@ -234,7 +256,7 @@ async def _handle_request_file(
234256
headers: Optional[Dict] = None,
235257
timeout: Optional[httpx.Timeout] = None,
236258
**kwargs,
237-
) -> Dict[str, Union[str, object]]:
259+
) -> Dict[str, Union[str, io.BytesIO]]:
238260
_url = url
239261
if params is not None:
240262
_url = append_query_params(_url, params)
@@ -253,7 +275,7 @@ async def _handle_request_file(
253275
)
254276
response.raise_for_status()
255277

256-
ret: Dict[str, Union[str, object]] = {}
278+
ret: Dict[str, Union[str, io.BytesIO]] = {}
257279
for item in file_result:
258280
if item in response.headers:
259281
ret[item] = response.headers[item]
@@ -288,3 +310,51 @@ async def _handle_request_file(
288310
raise
289311

290312
# pylint: enable-msg=too-many-locals,too-many-branches
313+
314+
# pylint: disable-msg=too-many-locals,too-many-branches
315+
async def _handle_request_raw(
316+
self,
317+
method: str,
318+
url: str,
319+
params: Optional[Dict] = None,
320+
addons: Optional[Dict] = None,
321+
headers: Optional[Dict] = None,
322+
timeout: Optional[httpx.Timeout] = None,
323+
**kwargs,
324+
) -> httpx.Response:
325+
_url = url
326+
if params is not None:
327+
_url = append_query_params(_url, params)
328+
if addons is not None:
329+
_url = append_query_params(_url, addons)
330+
_headers = self._config.headers
331+
if headers is not None:
332+
_headers.update(headers)
333+
if timeout is None:
334+
timeout = httpx.Timeout(30.0, connect=10.0)
335+
336+
try:
337+
client = httpx.AsyncClient(timeout=timeout)
338+
req = client.build_request(method, _url, headers=_headers, **kwargs)
339+
return await client.send(req, stream=True)
340+
341+
except httpx.HTTPError as e1:
342+
if isinstance(e1, httpx.HTTPStatusError):
343+
status_code = e1.response.status_code or 500
344+
try:
345+
json_object = json.loads(e1.response.text)
346+
raise DeepgramApiError(
347+
json_object.get("err_msg"),
348+
str(status_code),
349+
json.dumps(json_object),
350+
) from e1
351+
except json.decoder.JSONDecodeError as e2:
352+
raise DeepgramUnknownApiError(e2.msg, str(status_code)) from e2
353+
except ValueError as e2:
354+
raise DeepgramUnknownApiError(str(e2), str(status_code)) from e2
355+
else:
356+
raise # pylint: disable-msg=try-except-raise
357+
except Exception: # pylint: disable-msg=try-except-raise
358+
raise
359+
360+
# pylint: enable-msg=too-many-locals,too-many-branches

deepgram/clients/abstract_sync_client.py

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,29 @@ def get(
6060
**kwargs,
6161
)
6262

63-
def post_file(
63+
def post_raw(
64+
self,
65+
url: str,
66+
options: Optional[Dict] = None,
67+
addons: Optional[Dict] = None,
68+
headers: Optional[Dict] = None,
69+
timeout: Optional[httpx.Timeout] = None,
70+
**kwargs,
71+
) -> httpx.Response:
72+
"""
73+
Make a POST request to the specified URL and return response in raw bytes.
74+
"""
75+
return self._handle_request_raw(
76+
"POST",
77+
url,
78+
params=options,
79+
addons=addons,
80+
headers=headers,
81+
timeout=timeout,
82+
**kwargs,
83+
)
84+
85+
def post_memory(
6486
self,
6587
url: str,
6688
file_result: List,
@@ -69,11 +91,11 @@ def post_file(
6991
headers: Optional[Dict] = None,
7092
timeout: Optional[httpx.Timeout] = None,
7193
**kwargs,
72-
) -> Dict[str, Union[str, io.BytesIO, object]]:
94+
) -> Dict[str, Union[str, io.BytesIO]]:
7395
"""
74-
Make a POST request to the specified URL and return a file response.
96+
Make a POST request to the specified URL and return response in memory.
7597
"""
76-
return self._handle_request_file(
98+
return self._handle_request_memory(
7799
"POST",
78100
url,
79101
file_result=file_result,
@@ -222,7 +244,7 @@ def _handle_request(
222244
# pylint: enable-msg=too-many-locals,too-many-branches
223245

224246
# pylint: disable-msg=too-many-branches,too-many-locals
225-
def _handle_request_file(
247+
def _handle_request_memory(
226248
self,
227249
method: str,
228250
url: str,
@@ -232,7 +254,7 @@ def _handle_request_file(
232254
headers: Optional[Dict] = None,
233255
timeout: Optional[httpx.Timeout] = None,
234256
**kwargs,
235-
) -> Dict[str, Union[str, io.BytesIO, object]]:
257+
) -> Dict[str, Union[str, io.BytesIO]]:
236258
_url = url
237259
if params is not None:
238260
_url = append_query_params(_url, params)
@@ -249,7 +271,7 @@ def _handle_request_file(
249271
response = client.request(method, _url, headers=_headers, **kwargs)
250272
response.raise_for_status()
251273

252-
ret: Dict[str, Union[str, object]] = {}
274+
ret: Dict[str, Union[str, io.BytesIO]] = {}
253275
for item in file_result:
254276
if item in response.headers:
255277
ret[item] = response.headers[item]
@@ -284,3 +306,51 @@ def _handle_request_file(
284306
raise
285307

286308
# pylint: disable-msg=too-many-branches,too-many-locals
309+
310+
# pylint: disable-msg=too-many-branches,too-many-locals
311+
def _handle_request_raw(
312+
self,
313+
method: str,
314+
url: str,
315+
params: Optional[Dict] = None,
316+
addons: Optional[Dict] = None,
317+
headers: Optional[Dict] = None,
318+
timeout: Optional[httpx.Timeout] = None,
319+
**kwargs,
320+
) -> httpx.Response:
321+
_url = url
322+
if params is not None:
323+
_url = append_query_params(_url, params)
324+
if addons is not None:
325+
_url = append_query_params(_url, addons)
326+
_headers = self._config.headers
327+
if headers is not None:
328+
_headers.update(headers)
329+
if timeout is None:
330+
timeout = httpx.Timeout(30.0, connect=10.0)
331+
332+
try:
333+
client = httpx.Client(timeout=timeout)
334+
req = client.build_request(method, _url, headers=_headers, **kwargs)
335+
return client.send(req, stream=True)
336+
337+
except httpx.HTTPError as e1:
338+
if isinstance(e1, httpx.HTTPStatusError):
339+
status_code = e1.response.status_code or 500
340+
try:
341+
json_object = json.loads(e1.response.text)
342+
raise DeepgramApiError(
343+
json_object.get("err_msg"),
344+
str(status_code),
345+
json.dumps(json_object),
346+
) from e1
347+
except json.decoder.JSONDecodeError as e2:
348+
raise DeepgramUnknownApiError(e2.msg, str(status_code)) from e2
349+
except ValueError as e2:
350+
raise DeepgramUnknownApiError(str(e2), str(status_code)) from e2
351+
else:
352+
raise # pylint: disable-msg=try-except-raise
353+
except Exception: # pylint: disable-msg=try-except-raise
354+
raise
355+
356+
# pylint: disable-msg=too-many-branches,too-many-locals

deepgram/clients/listen/v1/websocket/options.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class LiveOptions(DataClassJsonMixin): # pylint: disable=too-many-instance-attr
5050
# since it gets translated to a string to be placed as a query parameter, will keep `str` for now
5151
# but will change this to `Optional[Union[bool, int]]` in a future release
5252
endpointing: Optional[Union[str, bool, int]] = field(
53-
default=None, metadata=dataclass_config(exclude=lambda f: f is None)
53+
default=None,
54+
metadata=dataclass_config(exclude=lambda f: f is None),
5455
)
5556
# pylint: enable=W0511
5657
extra: Optional[Union[List[str], str]] = field(
@@ -137,10 +138,18 @@ def check(self):
137138
logger.setLevel(verboselogs.ERROR)
138139

139140
if self.tier:
140-
logger.error(
141+
logger.warning(
141142
"WARNING: Tier is deprecated. Will be removed in a future version."
142143
)
143144

145+
if isinstance(self.endpointing) == str:
146+
logger.warning(
147+
"WARNING: endpointing's current type previous was `Optional[str]` which is incorrect"
148+
" for backward compatibility we are keeping it as `Optional[Union[str, bool, int]]`"
149+
" since it gets translated to a string to be placed as a query parameter, will keep `str` for now"
150+
" but will change this to `Optional[Union[bool, int]]` in a future release"
151+
)
152+
144153
logger.setLevel(prev)
145154

146155
return True

0 commit comments

Comments
 (0)