aiohttp monkey patch to work with nest_asyncio

617 Views Asked by At

I used nest_asyncio in my python project. And everything works perfect except that aiohttp function get_running_loop has some warning message that fill all my logs.

The aiohttp used the implementation for their get_running_loop similar to:

def get_running_loop(loop=None):
    if loop is None:
        loop = asyncio.get_event_loop()
    if not loop.is_running():
        warnings.warn("The object should be created from async function",
                                 DeprecationWarning,
                                 stacklevel=3)

In last versions they even throw an exception:

def get_running_loop() -> asyncio.AbstractEventLoop:
    loop = asyncio.get_event_loop()
    if not loop.is_running():
        raise RuntimeError(
            "The object should be created within an async function"
        )
    return loop

But the nest_asyncio loop is_running method never returns True to not block nested calls of run_until_complete.

I tried to do a monkey patch before other imports like this:

import aiohttp.helpers

def _get_running_loop(loop=None):
    if loop is None:
        loop = asyncio.get_event_loop()
    return loop

aiohttp.helpers.get_running_loop = _get_running_loop

And after all imports I see that the aiohttp.helpers.get_running_loop points to my implementation. But the calls of aiohttp functions still use its own implementation (because of relative import or what else):

async with aiohttp.ClientSession() as session:

prints to log:

  The object should be created from async function
  File ".../lib/python3.7/site-packages/aiohttp/client.py", line 225, in __init__
    cookie_jar = CookieJar(loop=loop)
  File ".../lib/python3.7/site-packages/aiohttp/cookiejar.py", line 55, in __init__
    super().__init__(loop=loop)
  File ".../lib/python3.7/site-packages/aiohttp/abc.py", line 146, in __init__
    self._loop = get_running_loop(loop)
  File ".../lib/python3.7/site-packages/aiohttp/helpers.py", line 276, in get_running_loop
    stack_info=True)

I would not like to fork all the aiohttp for this or analize callstack in the nest_asyncio to have special responses for aiohttp. Is it possible to have here a simple solution like a monkey patch and how can I patch the get_running_loop that is used inside asyncio?

1

There are 1 best solutions below

0
On

I guess you also need to monkey patch the abc module:

import aiohttp.abc
aiohttp.abc.get_running_loop = _get_running_loop

In vaex I do something similar to scikit-learn, but by inspecting all modules, see https://github.com/vaexio/vaex/blob/95aecc9ae1a4285babd42a104d64ed52b5130d2d/packages/vaex-ml/vaex/ml/__init__.py#L284