首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当status_code = 200时,使用python请求重试

当status_code = 200时,使用python请求重试
EN

Stack Overflow用户
提问于 2021-11-05 14:47:15
回答 1查看 2.7K关注 0票数 0

我要发送请求的API有一些不寻常的响应格式

总是返回status_code = 200

  1. 返回的json中有一个额外的error键,详细说明了响应的实际状态:

2.1。error = 0意味着它成功完成了

2.2。error != 0的意思是出了什么问题,

我尝试在urlib3中使用Retry类,但到目前为止,我了解它只使用响应中的status_code,而不是它的实际内容。

还有其他选择吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-05 15:00:13

如果我没听错,那么有两种情况需要你处理:

  1. 任何来自web服务器的非200响应(例如,500,403等)

  1. 每当API返回JSON响应中的“error”的非零值时,服务器总是使用HTTP200进行响应,即使您的请求是错误的。

考虑到我们需要处理触发重试的两种完全不同的情况,那么编写自己的重试处理程序就会更容易,而不是试图用urllib3库或类似的方法黑进去,因为我们可以具体指定需要重试的情况。

您可能会尝试类似这样的方法,这种方法还考虑到您为确定是否存在重复错误情况而提出的请求数量,在API响应错误或HTTP错误的情况下,我们使用一种‘指数退避’方法(通过对我最初答案的注释)进行重试,这样您就不会经常对服务器征税--这意味着每次重试在重试之前都有一个不同的“睡眠”期间,直到我们达到一个MAX_RETRY计数为止,正如我们所写的,第一次重试尝试是1秒,第二次重试是2秒,第三次重试是4秒,等,这将允许服务器追赶,如果它必须,而不是只是不断地过度征税服务器。

代码语言:javascript
运行
复制
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服务器获取数据,然后在没有遇到错误的情况下进行错误处理:

代码语言:javascript
运行
复制
# 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的输出,即使此部分包含在另一个函数中。您只需要这两个依赖函数(这样做是为了减少代码重复)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69855084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档