Skip to content

Commit 3bb2e8e

Browse files
Merge pull request #249 from dvonthenen/timeout-rest-async-client
Implement Timeout for Async REST API Call
2 parents 8f63e8c + 476f08d commit 3bb2e8e

File tree

5 files changed

+54
-20
lines changed

5 files changed

+54
-20
lines changed

deepgram/clients/abstract_async_client.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import httpx
66
import json
77

8+
from .helpers import append_query_params
89
from ..options import DeepgramClientOptions
910
from .errors import DeepgramError, DeepgramApiError, DeepgramUnknownApiError
1011
from .helpers import append_query_params
@@ -20,6 +21,8 @@ class AbstractAsyncRestClient:
2021
Args:
2122
url (Dict[str, str]): The base URL for the RESTful API, including any path segments.
2223
headers (Optional[Dict[str, Any]]): Optional HTTP headers to include in requests.
24+
params (Optional[Dict[str, Any]]): Optional query parameters to include in requests.
25+
timeout (Optional[httpx.Timeout]): Optional timeout configuration for requests.
2326
2427
Exceptions:
2528
DeepgramApiError: Raised for known API errors.
@@ -29,70 +32,80 @@ class AbstractAsyncRestClient:
2932
def __init__(self, config: DeepgramClientOptions):
3033
if config is None:
3134
raise DeepgramError("Config are required")
32-
3335
self.config = config
34-
self.client = httpx.AsyncClient()
3536

36-
async def get(self, url: str, options=None, addons=None, **kwargs):
37+
async def get(self, url: str, options=None, addons=None, timeout=None, **kwargs):
3738
return await self._handle_request(
3839
"GET",
3940
url,
4041
params=options,
4142
addons=addons,
43+
timeout=timeout,
4244
headers=self.config.headers,
4345
**kwargs
4446
)
4547

46-
async def post(self, url: str, options=None, addons=None, **kwargs):
48+
async def post(self, url: str, options=None, addons=None, timeout=None, **kwargs):
4749
return await self._handle_request(
4850
"POST",
4951
url,
5052
params=options,
5153
addons=addons,
54+
timeout=timeout,
5255
headers=self.config.headers,
5356
**kwargs
5457
)
5558

56-
async def put(self, url: str, options=None, addons=None, **kwargs):
59+
async def put(self, url: str, options=None, addons=None, timeout=None, **kwargs):
5760
return await self._handle_request(
5861
"PUT",
5962
url,
6063
params=options,
6164
addons=addons,
65+
timeout=timeout,
6266
headers=self.config.headers,
6367
**kwargs
6468
)
6569

66-
async def patch(self, url: str, options=None, addons=None, **kwargs):
70+
async def patch(self, url: str, options=None, addons=None, timeout=None, **kwargs):
6771
return await self._handle_request(
6872
"PATCH",
6973
url,
7074
params=options,
7175
addons=addons,
76+
timeout=timeout,
7277
headers=self.config.headers,
7378
**kwargs
7479
)
7580

76-
async def delete(self, url: str, options=None, addons=None, **kwargs):
81+
async def delete(self, url: str, options=None, addons=None, timeout=None, **kwargs):
7782
return await self._handle_request(
7883
"DELETE",
7984
url,
8085
params=options,
8186
addons=addons,
87+
timeout=timeout,
8288
headers=self.config.headers,
8389
**kwargs
8490
)
8591

86-
async def _handle_request(self, method, url, params, addons, headers, **kwargs):
92+
async def _handle_request(
93+
self, method, url, params, addons, timeout, headers, **kwargs
94+
):
8795
new_url = url
8896
if params is not None:
8997
new_url = append_query_params(new_url, params)
9098
if addons is not None:
9199
new_url = append_query_params(new_url, addons)
92100

101+
if timeout is None:
102+
timeout = httpx.Timeout(30.0, connect=10.0)
103+
93104
try:
94-
with httpx.Client() as client:
95-
response = client.request(method, new_url, headers=headers, **kwargs)
105+
async with httpx.AsyncClient(timeout=timeout) as client:
106+
response = await client.request(
107+
method, new_url, headers=headers, **kwargs
108+
)
96109
response.raise_for_status()
97110
return response.text
98111
except httpx._exceptions.HTTPError as e:

deepgram/clients/abstract_sync_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class AbstractSyncRestClient:
3131
def __init__(self, config: DeepgramClientOptions):
3232
if config is None:
3333
raise DeepgramError("Config are required")
34-
3534
self.config = config
3635

3736
def get(self, url: str, options=None, addons=None, timeout=None, **kwargs):
@@ -97,7 +96,7 @@ def _handle_request(self, method, url, params, addons, headers, timeout, **kwarg
9796
new_url = append_query_params(new_url, addons)
9897

9998
if timeout is None:
100-
timeout = httpx.Timeout(10.0, connect=10.0)
99+
timeout = httpx.Timeout(30.0, connect=10.0)
101100

102101
try:
103102
with httpx.Client(timeout=timeout) as client:

deepgram/clients/prerecorded/v1/async_client.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Use of this source code is governed by a MIT license that can be found in the LICENSE file.
33
# SPDX-License-Identifier: MIT
44

5+
import httpx
6+
import logging, verboselogs
57
import json
68
import logging, verboselogs
79

@@ -47,14 +49,15 @@ async def transcribe_url(
4749
source: UrlSource,
4850
options: PrerecordedOptions = None,
4951
addons: dict = None,
52+
timeout: httpx.Timeout = None,
5053
endpoint: str = "v1/listen",
5154
) -> PrerecordedResponse:
5255
self.logger.debug("PreRecordedClient.transcribe_url ENTER")
5356

5457
if options is not None and options.callback is not None:
5558
self.logger.debug("PreRecordedClient.transcribe_url LEAVE")
5659
return await self.transcribe_url_callback(
57-
source, options["callback"], options, addons, endpoint
60+
source, options["callback"], options, addons, timeout, endpoint
5861
)
5962

6063
url = f"{self.config.url}/{endpoint}"
@@ -72,7 +75,9 @@ async def transcribe_url(
7275
options = json.loads(options.to_json())
7376
self.logger.info("options: %s", options)
7477
self.logger.info("addons: %s", addons)
75-
result = await self.post(url, options=options, addons=addons, json=body)
78+
result = await self.post(
79+
url, options=options, addons=addons, json=body, timeout=timeout
80+
)
7681
self.logger.info("json: %s", result)
7782
res = PrerecordedResponse.from_json(result)
7883
self.logger.verbose("result: %s", res)
@@ -102,6 +107,7 @@ async def transcribe_url_callback(
102107
callback: str,
103108
options: PrerecordedOptions = None,
104109
addons: dict = None,
110+
timeout: httpx.Timeout = None,
105111
endpoint: str = "v1/listen",
106112
) -> AsyncPrerecordedResponse:
107113
self.logger.debug("PreRecordedClient.transcribe_url_callback ENTER")
@@ -124,7 +130,9 @@ async def transcribe_url_callback(
124130
options = json.loads(options.to_json())
125131
self.logger.info("options: %s", options)
126132
self.logger.info("addons: %s", addons)
127-
result = await self.post(url, options=options, addons=addons, json=body)
133+
result = await self.post(
134+
url, options=options, addons=addons, json=body, timeout=timeout
135+
)
128136
self.logger.info("json: %s", result)
129137
res = AsyncPrerecordedResponse.from_json(result)
130138
self.logger.verbose("result: %s", res)
@@ -152,14 +160,15 @@ async def transcribe_file(
152160
source: FileSource,
153161
options: PrerecordedOptions = None,
154162
addons: dict = None,
163+
timeout: httpx.Timeout = None,
155164
endpoint: str = "v1/listen",
156165
) -> PrerecordedResponse:
157166
self.logger.debug("PreRecordedClient.transcribe_file ENTER")
158167

159168
if options is not None and options.callback is not None:
160169
self.logger.debug("PreRecordedClient.transcribe_file LEAVE")
161170
return await self.transcribe_file_callback(
162-
source, options["callback"], options, addons, endpoint
171+
source, options["callback"], options, addons, timeout, endpoint
163172
)
164173

165174
url = f"{self.config.url}/{endpoint}"
@@ -178,7 +187,9 @@ async def transcribe_file(
178187
options = json.loads(options.to_json())
179188
self.logger.info("options: %s", options)
180189
self.logger.info("addons: %s", addons)
181-
result = await self.post(url, options=options, addons=addons, content=body)
190+
result = await self.post(
191+
url, options=options, addons=addons, content=body, timeout=timeout
192+
)
182193
self.logger.info("json: %s", result)
183194
res = PrerecordedResponse.from_json(result)
184195
self.logger.verbose("result: %s", res)
@@ -208,6 +219,7 @@ async def transcribe_file_callback(
208219
callback: str,
209220
options: PrerecordedOptions = None,
210221
addons: dict = None,
222+
timeout: httpx.Timeout = None,
211223
endpoint: str = "v1/listen",
212224
) -> AsyncPrerecordedResponse:
213225
self.logger.debug("PreRecordedClient.transcribe_file_callback ENTER")
@@ -231,7 +243,9 @@ async def transcribe_file_callback(
231243
options = json.loads(options.to_json())
232244
self.logger.info("options: %s", options)
233245
self.logger.info("addons: %s", addons)
234-
result = await self.post(url, options=options, addons=addons, json=body)
246+
result = await self.post(
247+
url, options=options, addons=addons, json=body, timeout=timeout
248+
)
235249
self.logger.info("json: %s", result)
236250
res = AsyncPrerecordedResponse.from_json(result)
237251
self.logger.verbose("result: %s", res)

deepgram/clients/prerecorded/v1/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def transcribe_url(
5656
if options is not None and options.callback is not None:
5757
self.logger.debug("PreRecordedClient.transcribe_url LEAVE")
5858
return self.transcribe_url_callback(
59-
source, options["callback"], options, addons, endpoint
59+
source, options["callback"], options, addons, timeout, endpoint
6060
)
6161

6262
url = f"{self.config.url}/{endpoint}"
@@ -167,7 +167,7 @@ def transcribe_file(
167167
if options is not None and options.callback is not None:
168168
self.logger.debug("PreRecordedClient.transcribe_file LEAVE")
169169
return self.transcribe_file_callback(
170-
source, options["callback"], options, addons, endpoint
170+
source, options["callback"], options, addons, timeout, endpoint
171171
)
172172

173173
url = f"{self.config.url}/{endpoint}"

examples/prerecorded/file/main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import os
66
from dotenv import load_dotenv
77
import logging, verboselogs
8+
from datetime import datetime, timedelta
89

910
from deepgram import (
1011
DeepgramClientOptions,
@@ -42,8 +43,15 @@ def main():
4243
punctuate=True,
4344
diarize=True,
4445
)
46+
47+
before = datetime.now()
4548
response = deepgram.listen.prerecorded.v("1").transcribe_file(payload, options)
49+
after = datetime.now()
50+
4651
print(response.to_json(indent=4))
52+
print("")
53+
difference = after - before
54+
print(f"time: {difference.seconds}")
4755

4856
except Exception as e:
4957
print(f"Exception: {e}")

0 commit comments

Comments
 (0)