How can I call an async function without await?

Question:

I have a controller action in aiohttp application.

async def handler_message(request):

    try:
        content = await request.json()
        perform_message(x,y,z)
    except (RuntimeError):
        print("error in perform fb message")
    finally:
        return web.Response(text="Done")

perform_message is async function. Now, when I call action I want that my action return as soon as possible and perform_message put in event loop.

In this way, perform_message isn’t executed

Asked By: Pasalino

||

Answers:

One way would be to use create_task function:

import asyncio

async def handler_message(request):
    ...
    loop = asyncio.get_event_loop()
    loop.create_task(perform_message(x,y,z))
    ...

As per the loop documentation, starting Python 3.10, asyncio.get_event_loop() is deprecated. If you’re trying to get a loop instance from a coroutine/callback, you should use asyncio.get_running_loop() instead. This method will not work if called from the main thread, in which case a new loop must be instantiated:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(perform_message(x, y, z))
loop.run_forever()

Furthermore, if the call is only made once throughout your program’s runtime and no other loop needs to be is instantiated (unlikely), you may use:

asyncio.run(perform_message(x, y, z))

This function creates an event loop and terminates it once the coroutine ends, therefore should only be used in the aforementioned scenario.

Answered By: freakish

Other way would be to use ensure_future function:

import asyncio

async def handler_message(request):
...
loop = asyncio.get_event_loop()
loop.ensure_future(perform_message(x,y,z))
...
Answered By: Pasalino

In simplest form:

import asyncio
from datetime import datetime

def _log(msg : str):
    print(f"{datetime.utcnow()} {msg}")

async def dummy(name, delay_sec):
    _log(f"{name} entering ...")
    await asyncio.sleep(delay_sec)
    _log(f"{name} done for the day!")

async def main():
    asyncio.create_task(dummy('dummy1', 5)) # last to finish
    asyncio.create_task(dummy('dummy2', 3)) # 2nd
    asyncio.create_task(dummy('dummy3', 1)) # First to finish

    _log(f"Yo I didn't wait for ya!")
    await asyncio.sleep(10)

asyncio.get_event_loop().run_until_complete(main())

Output:

2022-09-18 00:53:13.428285 Yo I didn't wait for ya!
2022-09-18 00:53:13.428285 dummy1 entering ...
2022-09-18 00:53:13.428285 dummy2 entering ...
2022-09-18 00:53:13.428285 dummy3 entering ...
2022-09-18 00:53:14.436801 dummy3 done for the day!
2022-09-18 00:53:16.437226 dummy2 done for the day!
2022-09-18 00:53:18.424755 dummy1 done for the day!
Answered By: user3761555
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.