Python 使用asyncio.gather时正确捕获aiohttp TimeoutError

Python 使用asyncio.gather时正确捕获aiohttp TimeoutError,python,concurrency,aiohttp,python-asyncio,Python,Concurrency,Aiohttp,Python Asyncio,这是我在堆栈溢出上的第一个问题,所以如果我做了一些愚蠢的事情或错过了一些东西,我向您道歉 我试图一次向多个api端点发出异步AIOHTTPGET请求,以检查这些页面的状态:结果应该是表单的三倍 (url,True,“200”)表示工作链接,以及(url,False,response_status)表示“有问题的链接”。这是每个调用的原子函数: async def ping_url(url、会话、标题、端点): 尝试: 与session.get((url+端点),timeout=5,headers

这是我在堆栈溢出上的第一个问题,所以如果我做了一些愚蠢的事情或错过了一些东西,我向您道歉

我试图一次向多个api端点发出异步AIOHTTPGET请求,以检查这些页面的状态:结果应该是表单的三倍 (url,True,“200”)表示工作链接,以及(url,False,response_status)表示“有问题的链接”。这是每个调用的原子函数:

async def ping_url(url、会话、标题、端点):
尝试:
与session.get((url+端点),timeout=5,headers=headers)异步作为响应:
返回url,(response.status==200),str(response.status)
例外情况除外,如e:
test_logger.info(url+“:“+e.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
返回url,False,repr(e)
使用asyncio.gather()将这些内容包装到一个函数中,该函数还创建了aiohttp会话:

异步定义ping_URL(URL列表,端点):
标题=…#无关
与ClientSession()作为会话异步:
尝试:
结果=等待asyncio.gather(*[ping_url(url、会话、标题、端点)\
对于url列表中的url],返回(异常=True)
例外情况除外,如e:
打印(报告(e))
返回结果
整体从一个看起来像这样的主管道调用:

url=…#无关
loop=asyncio.get\u event\u loop()
尝试:
循环。运行_直到_完成(ping_URL(URL,端点))
例外情况除外,如e:
通过
最后:
loop.close()
这在大多数情况下都有效,但如果列表很长,我会注意到,一旦我得到一个

TimeoutError
执行循环停止,在第一个URL超时后,我得到所有其他URL的TimeoutError。如果我在最里面的函数中省略超时,我会得到更好的结果,但是它不再那么快了。有没有一种方法可以控制单个api调用的超时,而不是整个URL列表的大超时


如果您能提供任何帮助,我都将不胜感激。由于这个问题,我的学士学位论文被卡住了。

您可以尝试为客户端会话设置会话超时。可以这样做:

async def ping_urls(urllist, endpoint):
    headers = ... # not relevant

    timeout = ClientTimeout(total=TIMEOUT_SECONDS)
    async with ClientSession(timeout=timeout) as session:
        try:
            results = await asyncio.gather(
               *[
                    ping_url(url, session, headers, endpoint)
                    for url in urllist
                ],
                return_exceptions=True
            )
        except Exception as e:
            print(repr(e))

        return results
这应该将ClientSession实例设置为具有
TIMEOUT\u SECONDS
作为超时。显然,您需要将该值设置为适当的值