Table of Contents
Overview
In Python, asyncio.gather()
is a function that allows you to run multiple coroutines or awaitable objects concurrently and get the results once they are complete. It was added to Python in version 3.4, as part of the asyncio
module.
asyncio.gather()
is used for writing concurrent code with the async/await
syntax, which is often a good fit for IO-bound and high-level structured network code. For example, you can use the asyncio.gather()
function to call multiple APIs in parallel and process the responses.
Syntax:
asyncio.gather(*aws, return_exceptions=False, loop=None)
Where:
*aws
: a sequence of coroutines or awaitable objects to be executed concurrently. The*
operator unpacks the sequence into individual arguments, allowing them to be passed to the function as separate arguments.return_exceptions
: a boolean value that controls how exceptions are handled. IfFalse
(the default), an exception raised by any awaitable object will be immediately propagated to the task that awaits onasyncio.gather()
. Other awaitable objects will continue to run and won’t be canceled. IfTrue
, exceptions will be captured and returned in the result list along with successful results.loop
: (deprecated since Python 3.8) the event loop to use for executing the awaitable objects. If not specified, the current event loop will be used.
The returned value of the asyncio.gather()
function is a Future
object that represents the aggregation of the results of the awaitable objects. When all awaitable objects are done, the Future
object’s result is a list of results with the same order as the input sequence. You can use the await
expression to get the result of the Future
object.
For more clarity, see the practical examples below.
Examples
Basic example
This one shows how to use the asyncio.gather()
function to run two coroutines that print some messages and sleep for a random amount of time:
import asyncio
import random
async def say_hello(name):
print(f"Hello, {name}!")
await asyncio.sleep(random.randint(1, 3))
print(f"Goodbye, {name}!")
return f"{name} is done"
async def main():
# run two coroutines concurrently and get the results
result = await asyncio.gather(
say_hello("Mr. Turtle"),
say_hello("Mr. Wolf")
)
# print the results
print(result)
# run the main coroutine
asyncio.run(main())
Output:
Hello, Mr. Turtle!
Hello, Mr. Wolf!
Goodbye, Mr. Turtle!
Goodbye, Mr. Wolf!
['Mr. Turtle is done', 'Mr. Wolf is done']
Advanced example
In this example, we’ll use the asyncio.gather()
function with the return_exceptions
parameter to handle exceptions raised by the awaitable objects. The return_exceptions
parameter can be True
or False
(the default). If True
, exceptions will be captured and returned in the result list along with successful results. If False
, an exception raised by any awaitable object will be immediately propagated to the task that awaits on asyncio.gather()
. Other awaitable objects will continue to run and won’t be canceled.
import asyncio
async def divide(x, y):
print(f"Dividing {x} by {y}")
await asyncio.sleep(1)
if y == 0:
raise ZeroDivisionError("Cannot divide by zero")
return x / y
async def main():
# run three coroutines concurrently and get the results
# one of them will raise an exception
result = await asyncio.gather(
divide(10, 2),
divide(20, 0),
divide(30, 5),
return_exceptions=True, # capture exceptions
)
# print the results or handle the exceptions
for r in result:
if isinstance(r, Exception):
print(f"Error: {r}")
else:
print(f"Result: {r}")
# run the main coroutine
asyncio.run(main())
Output:
Dividing 10 by 2
Dividing 20 by 0
Dividing 30 by 5
Result: 5.0
Error: Cannot divide by zero
Result: 6.0
Conclusion
You’ve learned the fundamentals of the asyncio.gather()
function and walked through a couple of code examples of using it in practice. At this point, you should be able to use it in your production projects with confidence. This tutorial ends here. Happy coding & enjoy programming with async/await
in modern Python.