Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python asyncio add_done_callback with async def

Tags:

I have 2 functions: The first one, def_a, is an asynchronous function and the second one is def_b which is a regular function and called with the result of def_a as a callback with the add_done_callback function.

My code looks like this:

import asyncio  def def_b(result):     next_number = result.result()     # some work on the next_number     print(next_number + 1)  async def def_a(number):     await some_async_work(number)     return number + 1  loop = asyncio.get_event_loop() task = asyncio.ensure_future(def_a(1)) task.add_done_callback(def_b) response = loop.run_until_complete(task) loop.close() 

And it's work perfectly.

The problem began when also the second function, def_b, became asynchronous. Now it looks like this:

async def def_b(result):     next_number = result.result()     # some asynchronous work on the next_number     print(next_number + 1) 

But now I can not provide it to the add_done_callback function, because it's not a regular function.

My question is- Is it possible and how can I provide def_b to the add_done_callback function if def_b is asynchronous?

like image 709
Yuval Pruss Avatar asked Jun 03 '17 14:06

Yuval Pruss


People also ask

Is Asyncio asynchronous?

asyncio is a library to write concurrent code using the async/await syntax. asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.

What does async def mean in Python?

The syntax async def introduces either a native coroutine or an asynchronous generator. The expressions async with and async for are also valid, and you'll see them later on. The keyword await passes function control back to the event loop. (It suspends the execution of the surrounding coroutine.)

How do I call a function asynchronously in Python?

To run an async function (coroutine) you have to call it using an Event Loop. Event Loops: You can think of Event Loop as functions to run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses. Example 1: Event Loop example to run async Function to run a single async function: Python3.

How do I use async await in Python?

An async function uses the await keyword to denote a coroutine. When using the await keyword, coroutines release the flow of control back to the event loop. To run a coroutine, we need to schedule it on the event loop. After scheduling, coroutines are wrapped in Tasks as a Future object.


1 Answers

add_done_callback is considered a "low level" interface. When working with coroutines, you can chain them in many ways, for example:

import asyncio   async def my_callback(result):     print("my_callback got:", result)     return "My return value is ignored"   async def coro(number):     await asyncio.sleep(number)     return number + 1   async def add_success_callback(fut, callback):     result = await fut     await callback(result)     return result   loop = asyncio.get_event_loop() task = asyncio.ensure_future(coro(1)) task = add_success_callback(task, my_callback) response = loop.run_until_complete(task) print("response:", response) loop.close() 

Keep in mind add_done_callback will still call the callback if your future raises an exception (but calling result.result() will raise it).

like image 178
Udi Avatar answered Sep 19 '22 09:09

Udi