gpt4 book ai didi

python - 如何管理单个aiohttp.ClientSession?

转载 作者:太空狗 更新时间:2023-10-29 21:44:58 24 4
gpt4 key购买 nike

作为一项学习练习,我正在尝试修改 aiohttp 的快速入门示例以使用单个 ClientSession 获取多个 url(文档建议通常每个应用程序应创建一个 ClientSession)。

import aiohttp
import asyncio

async def fetch(session, url):
async with session.get(url) as response:
return await response.text()

async def main(url, session):
print(f"Starting '{url}'")
html = await fetch(session, url)
print(f"'{url}' done")

urls = (
"https://python.org",
"https://twitter.com",
"https://tumblr.com",
"https://example.com",
"https://github.com",
)

loop = asyncio.get_event_loop()
session = aiohttp.ClientSession()
loop.run_until_complete(asyncio.gather(
*(loop.create_task(main(url, session)) for url in urls)
))
# session.close() <- this doesn't make a difference

但是,在协程之外创建 ClientSession 显然不是可行的方法:

➜ python 1_async.py1_async.py:30: UserWarning: Creating a client session outside of coroutine is a very dangerous idea  session = aiohttp.ClientSession()Creating a client session outside of coroutineclient_session: Starting 'https://python.org'Starting 'https://twitter.com'Starting 'https://tumblr.com'Starting 'https://example.com'Starting 'https://github.com''https://twitter.com' done'https://example.com' done'https://github.com' done'https://python.org' done'https://tumblr.com' done1_async.py:34: RuntimeWarning: coroutine 'ClientSession.close' was never awaited  session.close()Unclosed client sessionclient_session: Unclosed connectorconnections: ['[(, 15024.110107067)]', '[(, 15024.147785039)]', '[(, 15024.252375415)]', '[(, 15024.292646968)]', '[(, 15024.342368087)]', '[(, 15024.466971983)]', '[(, 15024.602057745)]', '[(, 15024.837045568)]']connector: 

FWIW, this was main before I attempted the above change:

async def main(url):
async with aiohttp.ClientSession() as session:
print(f"Starting '{url}'")
html = await fetch(session, url)
print(f"'{url}' done")

执行此操作的正确方法是什么?我考虑过将 url 列表传递给 main,但无法使其以非顺序方式工作。

最佳答案

在协程之外创建客户端 session 是一个非常危险的想法,因为当您创建它时,它会绑定(bind)到当前循环。如果之后更改运行循环,它将挂起。但如果你足够小心地使用它,你可以忽略它。 Related doc .

至于我,我只是忽略了这个警告。但克服它也很容易:

async def create_session():
return aiohttp.ClientSession()

session = asyncio.get_event_loop().run_until_complete(create_session())

此外,您不需要显式创建一个 Task 对象,只需执行这个协程函数即可:

loop.run_until_complete(asyncio.gather(
*(main(url, session) for url in urls)
))

最后,不要忘记 close 是一个协程。您应该使用 loop.run_until_complete(session.close()) 来关闭 session

顺便说一句,如果你想创建一个类似异步的循环,你可以引用 my another answer

关于python - 如何管理单个aiohttp.ClientSession?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51908915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com