Skip to content

Commit d1342a7

Browse files
committed
refactor request error and timeout
1 parent f02714c commit d1342a7

File tree

1 file changed

+54
-27
lines changed

1 file changed

+54
-27
lines changed

umapi_client/connection.py

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,44 @@
3434
from .version import __version__ as umapi_version
3535

3636

37+
class APIResult:
38+
success_codes = [200, 201, 204]
39+
timeout_codes = [429, 502, 503, 504]
40+
client_error = lambda self, x: 201 <= x < 200
41+
request_error = lambda self, x: 400 <= x < 500
42+
43+
def __init__(self, result=None, success=False, timeout=None):
44+
self.result = result
45+
self.success = success
46+
self.timeout = timeout
47+
48+
def check_result(self):
49+
if self.result.status_code in self.success_codes:
50+
self.success = True
51+
return self
52+
if self.result.status_code in self.timeout_codes:
53+
self.success = False
54+
self.timeout = self.get_timeout()
55+
return self
56+
print("STATUS", self.result.status_code)
57+
if self.client_error(self.result.status_code):
58+
raise ClientError("Unexpected HTTP Status {:d}: {}".format(self.result.status_code, self.result.text), self.result)
59+
if self.request_error(self.result.status_code):
60+
raise RequestError(self.result)
61+
raise ServerError(self.result)
62+
63+
def get_timeout(self):
64+
if "Retry-After" in self.result.headers:
65+
advice = self.result.headers["Retry-After"]
66+
advised_time = parsedate_tz(advice)
67+
if advised_time is not None:
68+
# header contains date
69+
return int(mktime_tz(advised_time) - time())
70+
else:
71+
# header contains delta seconds
72+
return int(advice)
73+
return 0
74+
3775
class Connection:
3876
"""
3977
An org-specific, authorized connection to the UMAPI service. Each method
@@ -439,38 +477,27 @@ def call():
439477
start_time = time()
440478
result = None
441479
for num_attempts in range(1, self.retry_max_attempts + 1):
480+
checked_result = None
442481
try:
443482
result = call()
444-
if result.status_code in [200,201,204]:
445-
return result
446-
elif result.status_code in [429, 502, 503, 504]:
447-
if self.logger: self.logger.warning("UMAPI timeout...service unavailable (code %d on try %d)",
448-
result.status_code, num_attempts)
449-
retry_wait = 0
450-
if "Retry-After" in result.headers:
451-
advice = result.headers["Retry-After"]
452-
advised_time = parsedate_tz(advice)
453-
if advised_time is not None:
454-
# header contains date
455-
retry_wait = int(mktime_tz(advised_time) - time())
456-
else:
457-
# header contains delta seconds
458-
retry_wait = int(advice)
459-
if retry_wait <= 0:
460-
# use exponential back-off with random delay
461-
delay = randint(0, self.retry_random_delay)
462-
retry_wait = (int(pow(2, num_attempts - 1)) * self.retry_first_delay) + delay
463-
elif 201 <= result.status_code < 400:
464-
raise ClientError("Unexpected HTTP Status {:d}: {}".format(result.status_code, result.text), result)
465-
elif 400 <= result.status_code < 500:
466-
raise RequestError(result)
467-
else:
468-
raise ServerError(result)
483+
checked_result = APIResult(result).check_result()
469484
except requests.Timeout:
470485
if self.logger: self.logger.warning("UMAPI connection timeout...(%d seconds on try %d)",
471486
self.timeout, num_attempts)
472-
retry_wait = 0
473-
result = None
487+
checked_result = APIResult(success=False, timeout=0)
488+
489+
if checked_result.success:
490+
return result
491+
492+
if self.logger: self.logger.warning("UMAPI timeout...service unavailable (code %d on try %d)",
493+
result.status_code, num_attempts)
494+
495+
retry_wait = checked_result.timeout
496+
if retry_wait <= 0:
497+
# use exponential back-off with random delay
498+
delay = randint(0, self.retry_random_delay)
499+
retry_wait = (int(pow(2, num_attempts - 1)) * self.retry_first_delay) + delay
500+
474501
if num_attempts < self.retry_max_attempts:
475502
if retry_wait > 0:
476503
if self.logger: self.logger.warning("Next retry in %d seconds...", retry_wait)

0 commit comments

Comments
 (0)