我正在使用以下代码段(请注意,仅显示部分代码段):
from urllib3.util import Retry
status_forcelist = (500, 502, 504)
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
method_whitelist=frozenset(['GET', 'POST'])
到目前为止,将对状态代码500
,502
,504
执行重试。但是,我打算重试任何状态代码,但不重试400
。是否有一种优美的方法来实现此目的,而不是为所有状态码填充/硬编码status_forcelist
?
答案 0 :(得分:3)
status_forcelist
仅用作白名单(使用后,可以称为黑名单),因此没有内置方法优雅。但是,您可以覆盖urllib3.util.retry.Retry.is_retry()
(如果需要,可以覆盖猴子补丁)将其视为黑名单,例如:
import urllib3.util.retry
class BlacklistRetry(urllib3.util.retry.Retry):
def is_retry(self, method, status_code, has_retry_after=False):
if not self._is_method_retryable(method):
return False
if self.status_forcelist and status_code not in self.status_forcelist:
# threat as a blacklist --------------^
return True
return (self.total and self.respect_retry_after_header and
has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES))
然后使用它代替原始的Retry
,只需将400
添加到其status_forcelist
。
答案 1 :(得分:1)
您可以从request
模块中获取代码-这样可以省去编写代码的麻烦。如果有任何新的介绍,您也将拥有它们:
import requests
from urllib3.util import Retry
status_forcelist = tuple( x for x in requests.status_codes._codes if x != 400)
print(status_forcelist)
输出:
(100, 101, 102, 103, 122, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302,
303, 304, 305, 306, 307, 308, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412,
413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 444, 449, 450,
451, 499, 500, 501, 502, 503, 504, 505, 506, 507, 509, 510, 511)
注意事项:wikipedia列出“自行创建” /非官方状态码以及9xx左右的专有状态码,但此列表未涵盖。 @zwer解决方案也将涵盖这些内容。