From 487f73cbb1b67468ae95a2c98d813a6c53e1a208 Mon Sep 17 00:00:00 2001 From: ariarijp Date: Thu, 7 Nov 2019 15:54:13 +0900 Subject: [PATCH 1/2] Add timeout option to Request class for better error handling. --- tests/test_client.py | 5 +++-- twitter_ads/http.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index 70fbbf3..717f1de 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -59,10 +59,11 @@ def test_accounts_with_options(): 'handle_rate_limit': True, 'retry_max': 1, 'retry_delay': 3000, - 'retry_on_status': [404, 500, 503] + 'retry_on_status': [404, 500, 503], + 'timeout': (1.0, 3.0) } ) assert client is not None assert isinstance(client, Client) - assert len(client.options) == 4 + assert len(client.options) == 5 diff --git a/twitter_ads/http.py b/twitter_ads/http.py index 5e59bd8..85bc2ab 100644 --- a/twitter_ads/http.py +++ b/twitter_ads/http.py @@ -89,6 +89,7 @@ def __oauth_request(self): retry_on_status = self._client.options.get('retry_on_status', [500, 503]) retry_count = 0 retry_after = None + timeout = self._client.options.get('timeout', None) consumer = OAuth1Session( self._client.consumer_key, @@ -101,7 +102,7 @@ def __oauth_request(self): while (retry_count <= retry_max): response = method(url, headers=headers, data=data, params=params, - files=files, stream=stream) + files=files, stream=stream, timeout=timeout) # do not retry on 2XX status code if 200 <= response.status_code < 300: break From ce2078c128a60695e09aec9015649880c3270d0a Mon Sep 17 00:00:00 2001 From: smaeda-ks Date: Thu, 21 Nov 2019 20:13:53 +0900 Subject: [PATCH 2/2] Adding retry_on_timeouts option --- twitter_ads/http.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/twitter_ads/http.py b/twitter_ads/http.py index 5e59bd8..c9d29ff 100644 --- a/twitter_ads/http.py +++ b/twitter_ads/http.py @@ -15,6 +15,7 @@ else: import http.client as httplib +from requests.exceptions import Timeout from requests_oauthlib import OAuth1Session from twitter_ads.utils import get_version from twitter_ads.error import Error @@ -87,6 +88,8 @@ def __oauth_request(self): retry_max = self._client.options.get('retry_max', 0) retry_delay = self._client.options.get('retry_delay', 1500) retry_on_status = self._client.options.get('retry_on_status', [500, 503]) + retry_on_timeouts = self._client.options.get('retry_on_timeouts', False) + timeout = self._client.options.get('timeout', None) retry_count = 0 retry_after = None @@ -100,8 +103,20 @@ def __oauth_request(self): method = getattr(consumer, self._method) while (retry_count <= retry_max): - response = method(url, headers=headers, data=data, params=params, - files=files, stream=stream) + try: + response = method(url, headers=headers, data=data, params=params, + files=files, stream=stream, timeout=timeout) + except Timeout as e: + if retry_on_timeouts: + if retry_count == retry_max: + raise Exception(e) + logger.warning("Timeout occurred: resume in %s seconds" + % (int(retry_delay) / 1000)) + time.sleep(int(retry_delay) / 1000) + retry_count += 1 + continue + raise Exception(e) + # do not retry on 2XX status code if 200 <= response.status_code < 300: break