Summary: in this tutorial, you’ll learn about the asyncio.wait()
function to run an iterable of awaitable objects concurrently.
Introduction to the Python asyncio wait() function
The asyncio.wait()
function runs an iterable of awaitables objects and blocks until a specified condition.
Here’s the syntax of the asyncio.wait()
function:
asyncio.wait(aws, *, timeout=None, return_when=ALL_COMPLETED)
Code language: Python (python)
The asyncio.wait()
function has the following parameters:
aws
is iterable of awaitable objects that you want to run concurrently.timeout
(eitherint
orfloat
) specifies a maximum number of seconds to wait before returning the result.return_when
indicates when the function should return. Thereturn_when
accepts one of the constants in the table below.
Constant | Description |
---|---|
FIRST_COMPLETED | Return when all awaitables are complete or canceled. |
FIRST_EXCEPTION | Return when any awaitable is complete by raising an exception. If no awaitable raises an exception, the FIRST_EXCEPTION is equivalent to ALL_COMPLETED . |
ALL_COMPLETED | Return when all awaitables are complete or cancelled. |
Note that these constants are in the asyncio
library so you can reference them like asyncio.FIRST_COMPLETED
The asyncio.wait()
returns two sets:
done, pending = await asyncio.wait(aws)
Code language: Python (python)
done
is a set of awaitables that are done.pending
is a set of awaitables that are pending.
Python asyncio wait() function examples
The following example illustrates how to use the asyncio.wait()
function:
import asyncio
from asyncio import create_task
class APIError(Exception):
pass
async def call_api(message, result=100, delay=3, raise_exception=False):
print(message)
await asyncio.sleep(delay)
if raise_exception:
raise APIError
else:
return result
async def main():
task_1 = create_task(call_api('calling API 1...', result=1, delay=1))
task_2 = create_task(call_api('calling API 2...', result=2, delay=2))
task_3 = create_task(call_api('calling API 3...', result=3, delay=3))
pending = (task_1, task_2, task_3)
while pending:
done, pending = await asyncio.wait(
pending,
return_when=asyncio.FIRST_COMPLETED
)
result = done.pop().result()
print(result)
asyncio.run(main())
Code language: Python (python)
How it works.
First, define the APIError
class that extends the Exception
class:
class APIError(Exception):
pass
Code language: Python (python)
Second, define the call_api()
function that simulates an asynchronous operation:
async def call_api(message, result=100, delay=3, raise_exception=False):
print(message)
await asyncio.sleep(delay)
if raise_exception:
raise APIError
else:
return result
Code language: Python (python)
Third, create three tasks that wrap the call_api()
coroutines. Each coroutine returns a different number:
task_1 = create_task(call_api('calling API 1...', result=1, delay=1))
task_2 = create_task(call_api('calling API 2...', result=2, delay=2))
task_3 = create_task(call_api('calling API 3...', result=3, delay=3))
pending = (task_1, task_2, task_3)
Code language: Python (python)
Finally, call the asyncio.wait()
function to run the tasks inside a while
loop. If all the tasks are complete, the pending will be empty, and the while
loop will exit. In each iteration, we get the completed task from the done
set and display the result:
while pending:
done, pending = await asyncio.wait(
pending,
return_when=asyncio.FIRST_COMPLETED
)
result = done.pop().result()
print(result)
Code language: Python (python)
Summary
- Use the
asyncio.wait()
to run tasks in an iterable concurrently.