fso*_*ety 4 python-3.x python-requests
我正在使用以下代码段(请注意,仅显示了部分代码段):
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'])
Run Code Online (Sandbox Code Playgroud)
截至目前,将重试状态代码500, 502, 504。但是,我打算重试任何状态代码而不是400. 有没有一种优雅的方法来实现这一点,而不是status_forcelist为所有状态代码填充/硬编码?
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))
Run Code Online (Sandbox Code Playgroud)
然后使用它代替原来的Retry并添加400到它的status_forcelist.
您可以从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)
Run Code Online (Sandbox Code Playgroud)
输出:
(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)
Run Code Online (Sandbox Code Playgroud)
警告:维基百科列出了“自己创建的”/非官方状态代码以及 9xx 周围的专有状态代码,但此列表并未涵盖这些代码。@zwer 解决方案也将涵盖这些。