如何在asycio后台线程中使用aiohttp

2024-09-24 22:33:06 发布

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

我正在尝试编写一个discord bot,用我从httprest调用获取的数据更新用户。在

由于discord.py使用了asyncio,我想我应该尝试遵循这个方法。在

async def my_background_task():

    print("starting BG task")
    await client.wait_until_ready()
    while not client.is_closed:
        requests.get(getMyUrl()).json()["dict_element"]
        #do more stuff

client.loop.create_task(my_background_task())
client.run("api key goes here")

使用sync“request”库就足够了。不过,我可以运行这个大约几个小时,直到它崩溃。我想是因为“请求”没能完成无休止的循环。在

^{pr2}$

所以我现在尝试使用aiohttp,但是在这个循环中遇到了异步循环的问题。在

关于如何处理这个问题,我还没有找到一个恰当的解释。我对python和异步函数非常陌生。在


Tags: 数据方法用户pyclientasynciotaskasync
2条回答

如果没有aiohttp版本的错误,很难猜测。但乍一看,我想说:

  • 不需要显式地将事件循环传递给ClientSession,它将自动选择当前的事件循环,因此您只需调用ClientSession()
  • fetch函数不应await respresp不是一个协同程序。您可能想return await resp.json()(并删除my_background_task中多余的.json()
  • my_method中,您已经在一个协程中运行,如async def所示。因此,要调用另一个协同例程,您应该await-对其进行操作,而不是创建新的事件循环并在该新循环中运行它。在
  • my_background_task中,您正在等待一个没有任何意义的东西:检查操作符await的优先级,您在一个协程中调用.__getitem__,然后等待{}的结果,这与您想要的结果相反。在
  • 仍然在这一行中,您不能在响应关闭后尝试读取响应的json主体(一旦退出async with,即只要fetch方法完成,响应就会关闭)。在
  • 最后,不应该在每个循环中都重新创建ClientSession。它的存在使得它可以在请求之间共享,所以您应该在my_background_task中创建一次并使用它

-

async def fetch(session, url):
    async with session.get(url) as resp:
        print(resp.status)
        return await resp.json()

async def my_background_task()
    print("starting BG task")
    await client.wait_until_ready()
    async with aiohttp.ClientSession() as session:
        while not client.is_closed:
            data = await fetch(session, "www.theinternet.com/restcall")
            element = data["dict_element"]

我通过另一个后台任务解决了这一问题,该任务将http响应作为全局变量并自行更新。在

我不知道我是不是应该这样做,但这正是我摆脱困境的原因。在

相关问题 更多 >