{"id":325,"date":"2024-01-28T10:55:11","date_gmt":"2024-01-28T10:55:11","guid":{"rendered":"https:\/\/learnpython.elegantwallp.com\/?p=325"},"modified":"2024-01-28T10:55:12","modified_gmt":"2024-01-28T10:55:12","slug":"python-asyncio-create_task","status":"publish","type":"post","link":"https:\/\/learnpython.elegantwallp.com\/2024\/01\/28\/python-asyncio-create_task\/","title":{"rendered":"Python asyncio.create_task()"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you\u2019ll learn how to use&nbsp;<code>asyncio.create_task()<\/code>&nbsp;function to run multiple tasks concurrently.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Simulating a long-running operation<\/h2>\n\n\n\n<p>To simulate a long-running operation, you can use the\u00a0<code>sleep()<\/code>\u00a0coroutine of the\u00a0<code>asyncio<\/code>\u00a0package. The\u00a0<code>sleep()<\/code>\u00a0function delays a specified number of the second:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>await asyncio.sleep(seconds)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Because\u00a0<code>sleep()<\/code>\u00a0is a coroutine, you need to use the\u00a0<code><a href=\"https:\/\/www.pythontutorial.net\/python-concurrency\/python-async-await\/\">await<\/a><\/code>\u00a0keyword. For example, the following uses the\u00a0<code>sleep()<\/code>\u00a0coroutine to simulate an API call:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>call_api()<\/code>&nbsp;is a coroutine. It displays a message, pauses a specified number of seconds (default to three seconds), and returns a result.<\/p>\n\n\n\n<p>The following program uses the\u00a0<code>call_api()<\/code>\u00a0twice and measures the time it takes to complete:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio import time async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result async def main(): start = time.perf_counter() price = await call_api('Get stock price of GOOG...', 300) print(price) price = await call_api('Get stock price of APPL...', 400) print(price) end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.') 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>Get stock price of GOOG... 300 Get stock price of APPL... 400 It took 6.0 second(s) to complete.<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works (focusing on the&nbsp;<code>main()<\/code>&nbsp;coroutine):<\/p>\n\n\n\n<p>First, start a timer to measure the time using the\u00a0<code>perf_counter()<\/code>\u00a0function of the\u00a0<code>time<\/code>\u00a0module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>start = time.perf_counter()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Second, call the\u00a0<code>call_api()<\/code>\u00a0coroutine and display the result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>price = await call_api('Get stock price of GOOG...', 300) print(price)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Third, call the\u00a0<code>call_api()<\/code>\u00a0a second time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>price = await call_api('Get stock price of APPL...', 400) print(price)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Finally, show the time the program takes to complete:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Because each&nbsp;<code>call_api()<\/code>&nbsp;takes three seconds, and calling it twice takes six seconds.<\/p>\n\n\n\n<p>In this example, we call a coroutine directly and don\u2019t put it on the event loop to run. Instead, we get a coroutine object and use the&nbsp;<code>await<\/code>&nbsp;keyword to execute it and get a result.<\/p>\n\n\n\n<p>The following picture illustrates the execution flow of the program:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/07\/python-create_task-async.svg\" alt=\"Python create_task Asynchronously\" class=\"wp-image-4128\"\/><\/figure>\n\n\n\n<p>In other words, we use&nbsp;<code>async<\/code>&nbsp;and&nbsp;<code>await<\/code>&nbsp;to write asynchronous code but can\u2019t run it concurrently. To run multiple operations concurrently, we\u2019ll need to use something called tasks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to Python tasks<\/h2>\n\n\n\n<p>A task is a wrapper of a coroutine that schedules the coroutine to run on the event loop as soon as possible.<\/p>\n\n\n\n<p>The scheduling and execution occur in a non-blocking manner. In other words, you can create a task and execute other code instantly while the task is running.<\/p>\n\n\n\n<p>Notice that the task is different from the&nbsp;<code>await<\/code>&nbsp;keyword that blocks the entire coroutine until the operation completes with a result.<\/p>\n\n\n\n<p>It\u2019s important that you can create multiple tasks and schedule them to run instantly on the event loop at the same time.<\/p>\n\n\n\n<p>To create a task, you pass a coroutine to the&nbsp;<code>create_task()<\/code>&nbsp;function of the&nbsp;<code>asyncio<\/code>&nbsp;package. The&nbsp;<code>create_task()<\/code>&nbsp;function returns a&nbsp;<code>Task<\/code>&nbsp;object.<\/p>\n\n\n\n<p>The following program illustrates how to create two tasks that schedule and execute the\u00a0<code>call_api()<\/code>\u00a0coroutine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio import time async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result async def main(): start = time.perf_counter() task_1 = asyncio.create_task( call_api('Get stock price of GOOG...', 300) ) task_2 = asyncio.create_task( call_api('Get stock price of APPL...', 300) ) price = await task_1 print(price) price = await task_2 print(price) end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.') 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>Get stock price of GOOG... Get stock price of APPL... 300 300 It took 3.0 second(s) to complete.<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, start a timer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>start = time.perf_counter()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Next, create a task and schedule it to run on the event loop immediately:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>task_1 = asyncio.create_task( call_api('Get stock price of GOOG...', 300) )<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Then, create another task and schedule it to run on the event loop immediately:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>task_2 = asyncio.create_task( call_api('Get stock price of APPL...', 400) )<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>After that, wait for the tasks to be completed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>price = await task_1 print(price) price = await task_2 print(price)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>It\u2019s important to use the&nbsp;<code>await<\/code>&nbsp;keyword to wait for the tasks at some point in the program.<\/p>\n\n\n\n<p>If we did not use the&nbsp;<code>await<\/code>&nbsp;keyword, Python would schedule the task to run but stopped it when the&nbsp;<code>asyncio.run()<\/code>&nbsp;shutdown the event loop.<\/p>\n\n\n\n<p>The following picture illustrates the execution flow of the program:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/07\/python-create_task-concurrency.svg\" alt=\"Python create_task Concurrency\" class=\"wp-image-4129\"\/><\/figure>\n\n\n\n<p>Finally, show the time it takes to complete the\u00a0<code>main()<\/code>\u00a0function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>By using the&nbsp;<code>create_task()<\/code>&nbsp;function, the program is much faster. The more tasks you run, the faster it is.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running other tasks while waiting<\/h2>\n\n\n\n<p>When the\u00a0<code>call_api<\/code>\u00a0is running, you can run other tasks. For example, the following program displays a message every second while waiting for the\u00a0<code>call_api<\/code>\u00a0tasks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import asyncio import time async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result async def show_message(): for _ in range(3): await asyncio.sleep(1) print('API call is in progress...') async def main(): start = time.perf_counter() message_task = asyncio.create_task( show_message() ) task_1 = asyncio.create_task( call_api('Get stock price of GOOG...', 300) ) task_2 = asyncio.create_task( call_api('Get stock price of APPL...', 300) ) price = await task_1 print(price) price = await task_2 print(price) await message_task end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.') 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>Get stock price of GOOG... Get stock price of APPL... API call is in progress... API call is in progress... API call is in progress... 300 300<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The following picture illustrates the execution flow:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/07\/python-create_task-running-other-tasks.svg\" alt=\"\" class=\"wp-image-4130\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you\u2019ll learn how to use&nbsp;asyncio.create_task()&nbsp;function to run multiple tasks concurrently. Simulating a long-running operation To simulate a long-running operation, you can use the\u00a0sleep()\u00a0coroutine of the\u00a0asyncio\u00a0package. The\u00a0sleep()\u00a0function delays a specified number of the second: Because\u00a0sleep()\u00a0is a coroutine, you need to use the\u00a0await\u00a0keyword. For example, the following uses the\u00a0sleep()\u00a0coroutine to simulate an API [&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-325","post","type-post","status-publish","format-standard","hentry","category-1-python-concurrency"],"_links":{"self":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/325","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=325"}],"version-history":[{"count":1,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/325\/revisions"}],"predecessor-version":[{"id":326,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/325\/revisions\/326"}],"wp:attachment":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/media?parent=325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/categories?post=325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/tags?post=325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}