def __call__(self, *args, **kwargs): self._sleep_between() for i, is_last_try in zip(count(), _is_last_gen(self.max_retries)): try: return self.func(*args, **kwargs) except GeocoderServiceError: if not is_last_try: logger.warning( 'RateLimiter caught an error, retrying ' '(%s/%s tries). Called with (*%r, **%r).', i, self.max_retries, args, kwargs, exc_info=True) self._sleep(self.error_wait_seconds) continue if self.swallow_exceptions: logger.warning( 'RateLimiter swallowed an error after %r retries. ' 'Called with (*%r, **%r).', i, args, kwargs, exc_info=True) return self.return_value_on_exception else: raise finally: self._last_call = self._clock()
def _handle_exc(self, args, kwargs): if self.swallow_exceptions: logger.warning( type(self).__name__ + " swallowed an error after %r retries. " "Called with (*%r, **%r).", self.max_retries, args, kwargs, exc_info=True, ) return self.return_value_on_exception else: raise
def _retries_gen(self, args, kwargs): for i, is_last_try in zip(count(), _is_last_gen(self.max_retries)): try: yield i # Run the function. except self._retry_exceptions: if is_last_try: yield True # The exception should be raised else: logger.warning( type(self).__name__ + " caught an error, retrying " "(%s/%s tries). Called with (*%r, **%r).", i, self.max_retries, args, kwargs, exc_info=True, ) yield False # The exception has been swallowed. continue else: # A successful run -- stop retrying: return # pragma: no cover
def get_retry_after(headers): """Return Retry-After header value in seconds. .. versionadded:: 2.2 """ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After # https://github.com/urllib3/urllib3/blob/1.26.4/src/urllib3/util/retry.py#L376 try: retry_after = headers['retry-after'] except KeyError: return None if not retry_after: # None, '' return None retry_after = retry_after.strip() # RFC7231 section-7.1.3: # Retry-After = HTTP-date / delay-seconds try: # Retry-After: 120 seconds = int(retry_after) except ValueError: # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT retry_date_tuple = email.utils.parsedate_tz(retry_after) if retry_date_tuple is None: logger.warning('Invalid Retry-After header: %s', retry_after) return None retry_date = email.utils.mktime_tz(retry_date_tuple) seconds = retry_date - time.time() if seconds < 0: seconds = 0 return seconds