{"id":335,"date":"2024-01-28T11:03:24","date_gmt":"2024-01-28T11:03:24","guid":{"rendered":"https:\/\/learnpython.elegantwallp.com\/?p=335"},"modified":"2024-01-28T11:03:25","modified_gmt":"2024-01-28T11:03:25","slug":"python-asyncio-gather","status":"publish","type":"post","link":"https:\/\/learnpython.elegantwallp.com\/2024\/01\/28\/python-asyncio-gather\/","title":{"rendered":"Python asyncio.gather()"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you\u2019ll learn how to use the Python&nbsp;<code>asyncio.gather()<\/code>&nbsp;function to run multiple asynchronous operations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to the Python asyncio.gather() function<\/h2>\n\n\n\n<p>Sometimes, you may want to run multiple asynchronous operations and get the results once they are complete. To do that you can use the\u00a0<code>asyncio.gather()<\/code>\u00a0function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>gather(*aws, return_exceptions=False) -> Future&#91;tuple&#91;()]]<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>asyncio.gather()<\/code>&nbsp;function has two parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>aws<\/code>\u00a0is a sequence of awaitable objects. If any object in the\u00a0<code>aws<\/code>\u00a0is a\u00a0coroutine, the\u00a0<code>asyncio.gather()<\/code>\u00a0function will automatically schedule it as a\u00a0task.<\/li>\n\n\n\n<li><code>return_exceptions<\/code>&nbsp;is&nbsp;<code>False<\/code>&nbsp;by default. If an exception occurs in an awaitable object, it is immediately propagated to the task that awaits on&nbsp;<code>asyncio.gather()<\/code>. Other awaitables will continue to run and&nbsp;<strong>won\u2019t be canceled<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p>The&nbsp;<code>asyncio.gather()<\/code>&nbsp;returns the results of awaitables as a tuple&nbsp;<strong>with the same order<\/strong>&nbsp;as you pass the awaitables to the function.<\/p>\n\n\n\n<p>If the\u00a0<code>return_exceptions<\/code>\u00a0is\u00a0<code>True<\/code>. The\u00a0<code>asyncio.gather()<\/code>\u00a0will add the\u00a0exception\u00a0if any to the result and not propagate the exception to the caller.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Python asyncio.gather() examples<\/h2>\n\n\n\n<p>Let\u2019s take some examples of using the&nbsp;<code>asyncio.gather()<\/code>&nbsp;function.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Using asyncio.gather() to run multiple asynchronous operations<\/h3>\n\n\n\n<p>The following example uses the\u00a0<code>asyncio.gather()<\/code>\u00a0to run two asynchronous operations and displays the results:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio async def call_api(message, result, delay=3): print(message) await asyncio.sleep(delay) return result async def main(): a, b = await asyncio.gather( call_api('Calling API 1 ...', 1), call_api('Calling API 2 ...', 2) ) print(a, b) asyncio.run(main())<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>Calling API 1 ... Calling API 2 ... 100 200<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define a coroutine\u00a0<code>call_api()<\/code>\u00a0that simulates an asynchronous operation. The\u00a0<code>call_api()<\/code>\u00a0displays a message, delays a number of seconds, and returns a result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>async def call_api(message, result, delay=3): print(message) await asyncio.sleep(delay) return result<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Second, use the\u00a0<code>asyncio.gather()<\/code>\u00a0function to run two\u00a0<code>call_api()<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>async def main(): a, b = await asyncio.gather( call_api('Calling API 1 ...', 100, 1), call_api('Calling API 2 ...', 200, 2) ) print(a, b)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The first coroutine takes 1 second and returns 100 while the second coroutine takes 2 seconds and returns 100.<\/p>\n\n\n\n<p>After 2 seconds, the gather returns the result as a tuple that contains the result of the first and second coroutines.<\/p>\n\n\n\n<p>Note that a is 100 and b is 200 which are the results of the corresponding coroutine that we pass to the&nbsp;<code>asyncio.gather()<\/code>&nbsp;function.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2) Using asyncio.gather() to run multiple asynchronous operations with exceptions<\/h3>\n\n\n\n<p>The following example shows how to use the\u00a0<code>asyncio.gather()<\/code>\u00a0function to execute multiple asynchronous operations where an operation raises an exception:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio class APIError(Exception): def __init__(self, message): self._message = message def __str__(self): return self._message async def call_api_failed(): await asyncio.sleep(3) raise APIError('API failed') async def call_api(message, result, delay=3): print(message) await asyncio.sleep(delay) return result async def main(): a, b, c = await asyncio.gather( call_api('Calling API 1 ...', 100, 1), call_api('Calling API 2 ...', 200, 2), call_api_failed() ) print(a, b, c) asyncio.run(main())<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define a new\u00a0<code>APIError<\/code>\u00a0exception class that inherits from the\u00a0<code>Exception<\/code>\u00a0class:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class APIError(Exception): def __init__(self, message): self._message = message def __str__(self): return self._message<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Second, define the\u00a0<code>call_api_failed()<\/code>\u00a0coroutine that delays 1 second and raises an\u00a0<code>APIError<\/code>\u00a0exception:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>async def call_api_failed(): await asyncio.sleep(3) raise APIError('API failed')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Third, pass three coroutines to the\u00a0<code>asyncio.gather()<\/code>\u00a0function. After one second, the\u00a0<code>call_api_failed()<\/code>\u00a0raises an exception that immediately propagates to the\u00a0<code>asyncio.gather()<\/code>\u00a0function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>async def main(): a, b, c = await asyncio.gather( call_api('Calling API 1 ...', 100, 1), call_api('Calling API 2 ...', 200, 2), call_api_failed() ) print(a, b, c)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>If you run the program, you\u2019ll see the&nbsp;<code>APIError<\/code>&nbsp;exception.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3) Using asyncio.gather() to return an exception in the result<\/h3>\n\n\n\n<p>To get the exception in the result, you set the\u00a0<code>return_exceptions<\/code>\u00a0parameter to\u00a0<code>True<\/code>\u00a0as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio class APIError(Exception): def __init__(self, message): self._message = message def __str__(self): return self._message async def call_api(message, result, delay=3): print(message) await asyncio.sleep(delay) return result async def call_api_failed(): await asyncio.sleep(1) raise APIError('API failed') async def main(): a, b, c = await asyncio.gather( call_api('Calling API 1 ...', 100, 1), call_api('Calling API 2 ...', 200, 2), call_api_failed(), return_exceptions=True ) print(a, b, c) asyncio.run(main())<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>Calling API 1 ... Calling API 2 ... 100 200 API failed<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>In this example, because the&nbsp;<code>return_exceptions<\/code>&nbsp;is set to&nbsp;<code>True<\/code>, the&nbsp;<code>asyncio.gather()<\/code>&nbsp;returns the exception as part of the result.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you\u2019ll learn how to use the Python&nbsp;asyncio.gather()&nbsp;function to run multiple asynchronous operations. Introduction to the Python asyncio.gather() function Sometimes, you may want to run multiple asynchronous operations and get the results once they are complete. To do that you can use the\u00a0asyncio.gather()\u00a0function: The&nbsp;asyncio.gather()&nbsp;function has two parameters: The&nbsp;asyncio.gather()&nbsp;returns the results of awaitables [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[],"class_list":["post-335","post","type-post","status-publish","format-standard","hentry","category-1-python-concurrency"],"_links":{"self":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/comments?post=335"}],"version-history":[{"count":1,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/335\/revisions"}],"predecessor-version":[{"id":336,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/335\/revisions\/336"}],"wp:attachment":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/media?parent=335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/categories?post=335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/tags?post=335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}