Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Learn Creating Tasks with asyncio.create_task() | Tasks and Scheduling
Python Asyncio in Depth

Creating Tasks with asyncio.create_task()

Swipe to show menu

Awaiting a coroutine directly runs it – but sequentially. To run coroutines concurrently, you need to schedule them as tasks. That's what asyncio.create_task() is for.

Coroutines vs Tasks

When you await a coroutine directly, the current coroutine pauses and waits for it to finish before continuing. No concurrency happens.

12345678910111213141516
import asyncio import nest_asyncio nest_asyncio.apply() async def fetch(source): print(f"Starting {source}") await asyncio.sleep(1) # Simulating I/O delay print(f"Done {source}") async def main(): # Sequential await fetch("source_A") await fetch("source_B") asyncio.run(main())

Wrapping a coroutine in asyncio.create_task() schedules it to run on the event loop immediately – without waiting for the current coroutine to finish.

12345678910111213141516171819
import asyncio import nest_asyncio nest_asyncio.apply() async def fetch(source): print(f"Starting {source}") await asyncio.sleep(1) # Simulating I/O delay print(f"Done {source}") async def main(): # Concurrent task_a = asyncio.create_task(fetch("source_A")) task_b = asyncio.create_task(fetch("source_B")) await task_a await task_b asyncio.run(main())

Both tasks start almost simultaneously. Awaiting them at the end just waits for their completion.

Retrieving Return Values

Tasks capture the return value of the coroutine. You retrieve it by awaiting the task:

12345678910111213141516171819202122232425
import asyncio import httpx import nest_asyncio nest_asyncio.apply() # Fetching a single post title async def fetch_title(client, post_id): url = f"https://jsonplaceholder.typicode.com/posts/{post_id}" response = await client.get(url) data = response.json() return data["title"] async def main(): async with httpx.AsyncClient() as client: task_1 = asyncio.create_task(fetch_title(client, 1)) task_2 = asyncio.create_task(fetch_title(client, 2)) title_1 = await task_1 title_2 = await task_2 print(f"Post 1: {title_1}") print(f"Post 2: {title_2}") asyncio.run(main())

Task States

A task moves through three states after creation:

  • Pending: scheduled but not yet complete;
  • Done: finished successfully;
  • Cancelled: stopped before completing.

You can check a task's state with task.done() and task.cancelled().

123456789101112131415161718
import asyncio import nest_asyncio nest_asyncio.apply() async def work(): await asyncio.sleep(1) return "result" async def main(): task = asyncio.create_task(work()) print(task.done()) # False – still pending result = await task print(task.done()) # True – completed print(result) # result asyncio.run(main())
question mark

What is the difference between await coroutine() and asyncio.create_task(coroutine())?

Select the correct answer

Everything was clear?

How can we improve it?

Thanks for your feedback!

Section 2. Chapter 1

Ask AI

expand

Ask AI

ChatGPT

Ask anything or try one of the suggested questions to begin our chat

Section 2. Chapter 1
some-alt