在类__init__上定义aiohttp ClientSession供以后重用

问题描述

我想创建一个持续到程序结束的持久会话,我有以下代码

import asyncio
import aiohttp
import atexit

class Session:
    def __init__(self):
        self._session = aiohttp.ClientSession()
        atexit.register(self._close_session)

    async def get(self,url):
        response = await self._session.request("GET",url)
        return await response.json()

    def _close_session(self):
        asyncio.run(self._session.close())


async def pullit():
    print(await session.get("https://raw.communitydragon.org/latest/game/data/characters/aatrox/aatrox.bin.json"))

session = Session()

asyncio.run(pullit()) # THIS THROWS: Timeout context manager should be used inside a task
asyncio.get_event_loop().run_until_complete(pullit()) #THIS RUNS OK

这在self._session.request的{​​{1}}行上引发了异常,我已经搜索了其他答案,但仍然给出相同的错误

问题:此错误的原因是什么?如果我想打开一个持续一个程序生命周期的会话,并且需要在一个类中(强制性)定义它,那怎么办?

其他:目前,我正在使用Timeout context manager should be used inside a task在程序结束时关闭会话(请参见上面的代码),这是一种的方式?如果没有,什么是更好的做法

更新:我找到了解决方案,它使用了atexit,但与上面的asyncio.get_event_loop().run_until_complete(...)不同吗?为什么一个人都可以毫无问题地运行,而3.7+ asyncio.run()却没有运行?


更新2:我最终得到了以下代码

asyncio.run()
#runner.py
import aiohttp
import asyncio


class Runner:
    def __init__(self,coro):
        self.coro = coro

    async def run(self):
        session = aiohttp.ClientSession()
        client.start_session(session)
        await self.coro
        client.close_session()
        await session.close()


def run(coro):
    runner = Runner(coro)
    return asyncio.run(runner.run())
#client.py
class Client:
    def __init__(self):
        self._session = None

    async def get(self,url)
        return await response.json()

    def start_session(self,session):
        self._session = session

    def close_session(self):
        self._session = None

好的,这一切都运行了,但是运行之后,它又抛出了我from .runner import run from .client import Client client = Client() async def pullit(): print(await client.get("https://raw.communitydragon.org/latest/game/data/characters/aatrox/aatrox.bin.json")) run(pullit()) ,我从没关闭过循环。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)