我要发送请求的API有一些不寻常的响应格式
总是返回status_code = 200
的
error
键,详细说明了响应的实际状态:2.1。error = 0
意味着它成功完成了
2.2。error != 0
的意思是出了什么问题,
我尝试在urlib3
中使用Retry类,但到目前为止,我了解它只使用响应中的status_code
,而不是它的实际内容。
还有其他选择吗?
发布于 2021-11-05 15:00:13
如果我没听错,那么有两种情况需要你处理:
考虑到我们需要处理触发重试的两种完全不同的情况,那么编写自己的重试处理程序就会更容易,而不是试图用urllib3库或类似的方法黑进去,因为我们可以具体指定需要重试的情况。
您可能会尝试类似这样的方法,这种方法还考虑到您为确定是否存在重复错误情况而提出的请求数量,在API响应错误或HTTP错误的情况下,我们使用一种‘指数退避’方法(通过对我最初答案的注释)进行重试,这样您就不会经常对服务器征税--这意味着每次重试在重试之前都有一个不同的“睡眠”期间,直到我们达到一个MAX_RETRY计数为止,正如我们所写的,第一次重试尝试是1秒,第二次重试是2秒,第三次重试是4秒,等,这将允许服务器追赶,如果它必须,而不是只是不断地过度征税服务器。
import requests
import time
MAX_RETRY = 5
def make_request():
'''This makes a single request to the server to get data from it.'''
# Replace 'get' with whichever method you're using, and the URL with the actual API URL
r = requests.get('http://api.example.com')
# If r.status_code is not 200, treat it as an error.
if r.status_code != 200:
raise RuntimeError(f"HTTP Response Code {r.status_code} received from server."
else:
j = r.json()
if j['error'] != 0:
raise RuntimeError(f"API Error Code {j['error']} received from server."
else:
return j
def request_with_retry(backoff_in_seconds=1):
'''This makes a request retry up to MAX_RETRY set above with exponential backoff.'''
attempts = 1
while True:
try:
data = make_request()
return data
except RuntimeError as err:
print(err)
if attempts > MAX_RETRY:
raise RuntimeError("Maximum number of attempts exceeded, aborting.")
sleep = backoff_in_seconds * 2 ** (attempts - 1)
print(f"Retrying request (attempt #{attempts}) in {sleep} seconds...")
time.sleep(sleep)
attempts += 1
然后,将这两个函数与下面的函数结合在一起,实际尝试从API服务器获取数据,然后在没有遇到错误的情况下进行错误处理:
# This code actually *calls* these functions which contain the request with retry and
# exponential backoff *and* the individual request process for a single request.
try:
data = request_with_retry()
except RuntimeError as err:
print(err)
exit(1)
在这段代码之后,您可以使用data
‘做一些事情’,即JSON(?)API的输出,即使此部分包含在另一个函数中。您只需要这两个依赖函数(这样做是为了减少代码重复)。
https://stackoverflow.com/questions/69855084
复制相似问题