1from __future__
import absolute_import
8from collections
import namedtuple
9from itertools
import takewhile
11from ..exceptions
import (
20from ..packages
import six
26RequestHistory = namedtuple(
27 "RequestHistory", [
"method",
"url",
"error",
"status",
"redirect_location"]
39 "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
40 "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
45 @DEFAULT_METHOD_WHITELIST.setter
48 "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
49 "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
57 "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
58 "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
63 @DEFAULT_REDIRECT_HEADERS_BLACKLIST.setter
66 "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
67 "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
75 "Using 'Retry.BACKOFF_MAX' is deprecated and "
76 "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead",
84 "Using 'Retry.BACKOFF_MAX' is deprecated and "
85 "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead",
91@six.add_metaclass(_RetryMeta)
93 """Retry configuration.
95 Each retry attempt will create a new Retry object with updated values, so
96 they can be safely reused.
98 Retries can be defined as a default for a pool::
100 retries = Retry(connect=5, read=2, redirect=5)
101 http = PoolManager(retries=retries)
102 response = http.request('GET', 'http://example.com/')
104 Or per-request (which overrides the default for the pool)::
106 response = http.request('GET', 'http://example.com/', retries=Retry(10))
108 Retries can be disabled by passing ``False``::
110 response = http.request('GET', 'http://example.com/', retries=False)
112 Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
113 retries are disabled, in which case the causing exception will be raised.
116 Total number of retries to allow. Takes precedence over other counts.
118 Set to ``None`` to remove this constraint and fall back on other
121 Set to ``0`` to fail on the first retry.
123 Set to ``False`` to disable and imply ``raise_on_redirect=False``.
126 How many connection-related errors to retry on.
128 These are errors raised before the request is sent to the remote server,
129 which we assume has not triggered the server to process the request.
131 Set to ``0`` to fail on the first retry of this type.
134 How many times to retry on read errors.
136 These errors are raised after the request was sent to the server, so the
137 request may have side-effects.
139 Set to ``0`` to fail on the first retry of this type.
142 How many redirects to perform. Limit this to avoid infinite redirect
145 A redirect is a HTTP response with a status code 301, 302, 303, 307 or
148 Set to ``0`` to fail on the first retry of this type.
150 Set to ``False`` to disable and imply ``raise_on_redirect=False``.
153 How many times to retry on bad status codes.
155 These are retries made on responses, where status code matches
156 ``status_forcelist``.
158 Set to ``0`` to fail on the first retry of this type.
161 How many times to retry on other errors.
163 Other errors are errors that are not connect, read, redirect or status errors.
164 These errors might be raised after the request was sent to the server, so the
165 request might have side-effects.
167 Set to ``0`` to fail on the first retry of this type.
169 If ``total`` is not set, it's a good idea to set this to 0 to account
170 for unexpected edge cases and avoid infinite retry loops.
172 :param iterable allowed_methods:
173 Set of uppercased HTTP method verbs that we should retry on.
175 By default, we only retry on methods which are considered to be
176 idempotent (multiple requests with the same parameters end with the
177 same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`.
179 Set to a ``False`` value to retry on any verb.
183 Previously this parameter was named ``method_whitelist``, that
184 usage is deprecated in v1.26.0 and will be removed in v2.0.
186 :param iterable status_forcelist:
187 A set of integer HTTP status codes that we should force a retry on.
188 A retry is initiated if the request method is in ``allowed_methods``
189 and the response status code is in ``status_forcelist``.
191 By default, this is disabled with ``None``.
193 :param float backoff_factor:
194 A backoff factor to apply between attempts after the second try
195 (most errors are resolved immediately by a second try without a
196 delay). urllib3 will sleep for::
198 {backoff factor} * (2 ** ({number of total retries} - 1))
200 seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
201 for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
202 than :attr:`Retry.DEFAULT_BACKOFF_MAX`.
204 By default, backoff is disabled (set to 0).
206 :param bool raise_on_redirect: Whether, if the number of redirects is
207 exhausted, to raise a MaxRetryError, or to return a response with a
208 response code in the 3xx range.
210 :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
211 whether we should raise an exception, or return a response,
212 if status falls in ``status_forcelist`` range and retries have
215 :param tuple history: The history of the request encountered during
216 each call to :meth:`~Retry.increment`. The list is in the order
217 the requests occurred. Each list item is of class :class:`RequestHistory`.
219 :param bool respect_retry_after_header:
220 Whether to respect Retry-After header on status codes defined as
221 :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
223 :param iterable remove_headers_on_redirect:
224 Sequence of headers to remove from the request when a response
225 indicating a redirect is returned before firing off the redirected
231 [
"HEAD",
"GET",
"PUT",
"DELETE",
"OPTIONS",
"TRACE"]
238 DEFAULT_REMOVE_HEADERS_ON_REDIRECT =
frozenset([
"Authorization"])
241 DEFAULT_BACKOFF_MAX = 120
251 allowed_methods=_Default,
252 status_forcelist=None,
254 raise_on_redirect=True,
255 raise_on_status=True,
257 respect_retry_after_header=True,
258 remove_headers_on_redirect=_Default,
260 method_whitelist=_Default,
263 if method_whitelist
is not _Default:
264 if allowed_methods
is not _Default:
266 "Using both 'allowed_methods' and "
267 "'method_whitelist' together is not allowed. "
268 "Instead only use 'allowed_methods'"
271 "Using 'method_whitelist' with Retry is deprecated and "
272 "will be removed in v2.0. Use 'allowed_methods' instead",
276 allowed_methods = method_whitelist
277 if allowed_methods
is _Default:
279 if remove_headers_on_redirect
is _Default:
288 if redirect
is False or total
is False:
290 raise_on_redirect =
False
301 [
h.lower()
for h
in remove_headers_on_redirect]
326 if "method_whitelist" not in kw
and "allowed_methods" not in kw:
327 if "method_whitelist" in self.__dict__:
329 "Using 'method_whitelist' with Retry is deprecated and "
330 "will be removed in v2.0. Use 'allowed_methods' instead",
338 return type(self)(**params)
341 def from_int(cls, retries, redirect=True, default=None):
342 """Backwards-compatibility for the old retries format."""
344 retries = default
if default
is not None else cls.
DEFAULT
349 redirect = bool(redirect)
and None
350 new_retries =
cls(retries, redirect=redirect)
351 log.debug(
"Converted retries value: %r -> %r", retries, new_retries)
355 """Formula for computing the current backoff
360 consecutive_errors_len =
len(
365 if consecutive_errors_len <= 1:
368 backoff_value = self.
backoff_factor * (2 ** (consecutive_errors_len - 1))
373 if re.match(
r"^\s*[0-9]+\s*$", retry_after):
374 seconds = int(retry_after)
377 if retry_date_tuple
is None:
378 raise InvalidHeader(
"Invalid Retry-After header: %s" % retry_after)
379 if retry_date_tuple[9]
is None:
384 retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:]
395 """Get the value of Retry-After in seconds."""
399 if retry_after
is None:
418 def sleep(self, response=None):
419 """Sleep between retry attempts.
421 This method will respect a server's ``Retry-After`` response header
422 and sleep the duration of the time requested. If that is not present, it
423 will use an exponential backoff. By default, the backoff factor is 0 and
424 this method will return immediately.
435 """Errors when we're fairly sure that the server did not receive the
436 request, so it should be safe to retry.
443 """Errors that occur after the request has been started, so we should
444 assume that the server began processing it.
446 return isinstance(err, (ReadTimeoutError, ProtocolError))
449 """Checks if a given HTTP method should be retried upon, depending if
450 it is included in the allowed_methods
454 if "method_whitelist" in self.__dict__:
456 "Using 'method_whitelist' with Retry is deprecated and "
457 "will be removed in v2.0. Use 'allowed_methods' instead",
460 allowed_methods = self.method_whitelist
464 if allowed_methods
and method.upper()
not in allowed_methods:
468 def is_retry(self, method, status_code, has_retry_after=False):
469 """Is this method/status code retryable? (Based on allowlists and control
470 variables such as the number of total retries to allow, whether to
471 respect the Retry-After header, whether this header is present, and
472 whether the returned status code is on the list of status codes to
473 be retried upon on the presence of the aforementioned header)
489 """Are we out of retries?"""
498 retry_counts = list(filter(
None, retry_counts))
502 return min(retry_counts) < 0
513 """Return a new Retry object with incremented retry counters.
515 :param response: A response object, or None, if the server did not
517 :type response: :class:`~urllib3.response.HTTPResponse`
518 :param Exception error: An error encountered during the request, or
519 None if the response was received successfully.
521 :return: A new ``Retry`` object.
523 if self.
total is False and error:
528 if total
is not None:
534 status_count = self.
status
538 redirect_location =
None
544 elif connect
is not None:
551 elif read
is not None:
556 if other
is not None:
561 if redirect
is not None:
563 cause =
"too many redirects"
572 if status_count
is not None:
581 new_retry = self.
new(
594 log.debug(
"Incremented Retry for (url='%s'): %r", url, new_retry)
600 "{cls.__name__}(total={self.total}, connect={self.connect}, "
601 "read={self.read}, redirect={self.redirect}, status={self.status})"
602 ).format(cls=type(self), self=self)
605 if item ==
"method_whitelist":
608 "Using 'method_whitelist' with Retry is deprecated and "
609 "will be removed in v2.0. Use 'allowed_methods' instead",
615 except AttributeError:
sleep_for_retry(self, response=None)
_is_read_error(self, err)
DEFAULT_REMOVE_HEADERS_ON_REDIRECT
increment(self, method=None, url=None, response=None, error=None, _pool=None, _stacktrace=None)
__init__(self, total=10, connect=None, read=None, redirect=None, status=None, other=None, allowed_methods=_Default, status_forcelist=None, backoff_factor=0, raise_on_redirect=True, raise_on_status=True, history=None, respect_retry_after_header=True, remove_headers_on_redirect=_Default, method_whitelist=_Default)
remove_headers_on_redirect
is_retry(self, method, status_code, has_retry_after=False)
respect_retry_after_header
from_int(cls, retries, redirect=True, default=None)
parse_retry_after(self, retry_after)
get_retry_after(self, response)
_is_connection_error(self, err)
_is_method_retryable(self, method)