aiohttp RuntimeError: await wasn't used with future
aiohttp RuntimeError: await wasn't used with future
我知道 ,但是那里的答案没有解决这里发生的事情。
使用aiohttp
时我运行出现以下错误:
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/selector_events.py", line 485, in sock_connect
return await fut
RuntimeError: await wasn't used with future
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fb28040f760>
这是关联的代码:
urls = # some list of URLs including `https://www.alphavantage.co/query?function=OVERVIEW&symbol=IBM&apikey=demo`.....
async def run_tasks():
session = aiohttp.ClientSession()
tasks = [session.get(url) for url in urls]
await asyncio.gather(*tasks)
await session.close()
asyncio.run(run_tasks())
看起来我正在正确等待事件循环,但我一直遇到这个问题,这是怎么回事?
版本:
aiohttp==3.7.4.post0
asyncio==3.4.3
Python 3.8.0
这里可能会发生两件事:
- 你没有
await
做你应该做的事情
- 您调用的 URL 是错误的请求,并且在您有机会查看实际情况之前事件循环出错。
By default aiohttp uses strict checks for HTTPS protocol. Certification checks can be relaxed by setting ssl to False
所以您使用的 urls
很可能达到了这个阈值,您将被踢出。更改行:
tasks = [session.get(url) for url in urls]
到
tasks = [session.get(url, ssl=False) for url in urls]
我知道这不能直接回答您的问题,但 aiohttp
request life-cycle 中实际上有一些异步调用,所以您必须在几个地方 await
:
import asyncio
import aiohttp
URL = "https://whosebug.com"
async def main():
session = aiohttp.ClientSession()
resp = await session.get(URL)
html = await resp.text()
print(f"{URL} <{resp.status}> ({len(html)})")
resp.release()
await session.close()
if __name__ == "__main__":
asyncio.run(main())
通常且更简单的方法是使用 context managers 以确保正确关闭所有剩余资源:
import asyncio
import aiohttp
URLS = [
"https://serverfault.com",
"https://whosebug.com",
]
async def fetch(session, url):
async with session.get(url) as resp:
html = await resp.text()
print(f"{url} <{resp.status}>")
return {url: len(html)}
async def main():
tasks = []
async with aiohttp.ClientSession() as session:
for url in URLS:
tasks.append(asyncio.create_task(fetch(session, url)))
data = await asyncio.gather(*tasks)
print(data)
if __name__ == "__main__":
asyncio.run(main())
测试:
$ python test.py
https://serverfault.com <200>
https://whosebug.com <200>
[{'https://serverfault.com': 143272}, {'https://whosebug.com': 191046}]
我知道
使用aiohttp
时我运行出现以下错误:
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/selector_events.py", line 485, in sock_connect
return await fut
RuntimeError: await wasn't used with future
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fb28040f760>
这是关联的代码:
urls = # some list of URLs including `https://www.alphavantage.co/query?function=OVERVIEW&symbol=IBM&apikey=demo`.....
async def run_tasks():
session = aiohttp.ClientSession()
tasks = [session.get(url) for url in urls]
await asyncio.gather(*tasks)
await session.close()
asyncio.run(run_tasks())
看起来我正在正确等待事件循环,但我一直遇到这个问题,这是怎么回事?
版本:
aiohttp==3.7.4.post0
asyncio==3.4.3
Python 3.8.0
这里可能会发生两件事:
- 你没有
await
做你应该做的事情 - 您调用的 URL 是错误的请求,并且在您有机会查看实际情况之前事件循环出错。
By default aiohttp uses strict checks for HTTPS protocol. Certification checks can be relaxed by setting ssl to False
所以您使用的 urls
很可能达到了这个阈值,您将被踢出。更改行:
tasks = [session.get(url) for url in urls]
到
tasks = [session.get(url, ssl=False) for url in urls]
我知道这不能直接回答您的问题,但 aiohttp
request life-cycle 中实际上有一些异步调用,所以您必须在几个地方 await
:
import asyncio
import aiohttp
URL = "https://whosebug.com"
async def main():
session = aiohttp.ClientSession()
resp = await session.get(URL)
html = await resp.text()
print(f"{URL} <{resp.status}> ({len(html)})")
resp.release()
await session.close()
if __name__ == "__main__":
asyncio.run(main())
通常且更简单的方法是使用 context managers 以确保正确关闭所有剩余资源:
import asyncio
import aiohttp
URLS = [
"https://serverfault.com",
"https://whosebug.com",
]
async def fetch(session, url):
async with session.get(url) as resp:
html = await resp.text()
print(f"{url} <{resp.status}>")
return {url: len(html)}
async def main():
tasks = []
async with aiohttp.ClientSession() as session:
for url in URLS:
tasks.append(asyncio.create_task(fetch(session, url)))
data = await asyncio.gather(*tasks)
print(data)
if __name__ == "__main__":
asyncio.run(main())
测试:
$ python test.py
https://serverfault.com <200>
https://whosebug.com <200>
[{'https://serverfault.com': 143272}, {'https://whosebug.com': 191046}]