后退以仅重试失败的API调用,而不是使用asyncio重试所有API调用

2024-09-28 21:03:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用一个有速率限制的API提取信息。我使用异步IO和aiohttp以异步方式来加速这个过程。我收集了10个电话,所以每次我同时打10个电话。如果我收到429,我会等待2分钟,然后重试。。。对于重试部分,我使用退避装饰器

我的问题是对10个呼叫执行重试,而不仅仅是对失败的呼叫执行重试。。。我不知道该怎么做:

@backoff.on_exception(backoff.expo,aiohttp.ClientError,max_tries=20,logger=my_logger)
async def get_symbols(size,position):
    async with aiohttp.ClientSession() as session:
        queries = get_tasks(session,size,position)
        responses = await asyncio.gather(*queries)
        print("gathering responses")
        for response in responses:
            if response.status == 429:
                print(response.headers)
                print("Code 429 received waiting for 2 minutes")
                print(response)
                time.sleep(120)
                raise aiohttp.ClientError()
            else:
                query_data = await response.read()

有没有人有办法只执行失败的调用,而不是执行整个调用


Tags: sizegetasyncaiohttpresponsesessionpositionresponses
1条回答
网友
1楼 · 发布于 2024-09-28 21:03:00

代码中有两个问题。首先是重复sleep您可能不了解^{}是如何工作的。它的全部要点是1)尝试,2)睡眠指数级增加延迟,如果出现错误,3)为您重试函数/协同程序。第二,是get_symbolsbackoff修饰,因此显然它作为一个整体被重试

如何改进

  1. 装饰个人请求功能
  2. backoff做它的“睡眠”工作
  3. aiohttp通过在^{}初始化器中设置raise_for_status=True来为非200 HTTP重定位代码生成代码,从而完成它的工作

它应该如下所示

@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_tries=20)
async def send_task(client, params):
    async with client.get('https://python.org/', params=params) as resp:
        return await resp.text()
   
def get_tasks(client, size, position):
    for params in get_param_list(size, position)
        yield send_task(client, params)   

async def get_symbols(size,position):
    async with aiohttp.ClientSession(raise_for_status=True) as client:
        tasks = get_tasks(session, size, position)
        responses = await asyncio.gather(*tasks)
        for response in responses:
            print(await response.read())

相关问题 更多 >