Sling Academy
Home/Python/Python asyncio.gather() function (with examples)

Python asyncio.gather() function (with examples)

Last updated: July 26, 2023

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. If False (the default), 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. If True, 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.

Next Article: Python: How to Define and Call Asynchronous Functions

Previous Article: Python asyncio.sleep() function (with examples)

Series: Python Asynchronous Programming Tutorials

Python

You May Also Like

  • Introduction to yfinance: Fetching Historical Stock Data in Python
  • Monitoring Volatility and Daily Averages Using cryptocompare
  • Advanced DOM Interactions: XPath and CSS Selectors in Playwright (Python)
  • Automating Strategy Updates and Version Control in freqtrade
  • Setting Up a freqtrade Dashboard for Real-Time Monitoring
  • Deploying freqtrade on a Cloud Server or Docker Environment
  • Optimizing Strategy Parameters with freqtrade’s Hyperopt
  • Risk Management: Setting Stop Loss, Trailing Stops, and ROI in freqtrade
  • Integrating freqtrade with TA-Lib and pandas-ta Indicators
  • Handling Multiple Pairs and Portfolios with freqtrade
  • Using freqtrade’s Backtesting and Hyperopt Modules
  • Developing Custom Trading Strategies for freqtrade
  • Debugging Common freqtrade Errors: Exchange Connectivity and More
  • Configuring freqtrade Bot Settings and Strategy Parameters
  • Installing freqtrade for Automated Crypto Trading in Python
  • Scaling cryptofeed for High-Frequency Trading Environments
  • Building a Real-Time Market Dashboard Using cryptofeed in Python
  • Customizing cryptofeed Callbacks for Advanced Market Insights
  • Integrating cryptofeed into Automated Trading Bots