What is Async/Await in Python

January 24, 2023 Python Asyncio

You can use the async/await pattern in Python to implement asynchronous programming.

In this tutorial, you will discover async/await in Python and exactly what it means and when to use it.

Let's get started.

What is Async/Await

Async/await refers to a pattern used for asynchronous programming.

In computer programming, the async/await pattern is a syntactic feature of many programming languages that allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function

-- Async/await, Wikipedia.

Asynchronous programming is a programming paradigm that does not block.

Instead, requests and function calls are issued and executed somehow in the background at some future time. This frees the caller to perform other activities and handle the results of issued calls at a later time when results are available or when the caller is interested.

You can learn more about asynchronous programming in the tutorial:

One way of implementing asynchronous programming in modern programming languages is to use the async/await pattern.

Generally, "async" defines a coroutine, and "await" suspends or yields execution to another coroutine from within a coroutine.

The pattern is used for asynchronous programming in many popular programming languages, such as JavaScript, Swift, Rust, and Python.

What is Async/Await in Python

Async/await was introduced in Python version 3.5.

New syntax features: PEP 492, coroutines with async and await syntax.

-- What’s New In Python 3.5

It was developed according to PEP 492 which describes how to add coroutines and await/async to Python.

It is proposed to make coroutines a proper standalone concept in Python, and introduce new supporting syntax. The ultimate goal is to help establish a common, easily approachable, mental model of asynchronous programming in Python and make it as close to synchronous programming as possible.

-- PEP 492 – Coroutines with async and await syntax

Specifically, this change introduced coroutines as first-class objects or types.

A coroutine is a function that can be suspended and resumed.

It is often defined as a generalized subroutine.

A subroutine can be executed, starting at one point and finishing at another point. Whereas, a coroutine can be executed then suspended, and resumed many times before finally terminating.

coroutine: Coroutines are a more generalized form of subroutines. Subroutines are entered at one point and exited at another point. Coroutines can be entered, exited, and resumed at many different points.

-- Python Glossary

You can learn more about coroutines in the tutorial:

It also introduced new expressions for making use of coroutines, collectively referred to as async/await.

PEP 492 greatly improves support for asynchronous programming in Python by adding awaitable objects, coroutine functions, asynchronous iteration, and asynchronous context managers.

-- What’s New In Python 3.5

What is the async/await syntax in Python?

What is Async

Async refers to a suite of expressions for working with coroutines.

This includes:

The "async def" expression defines a coroutine, but the "async for" and "async with" expressions can only be used within a coroutine, e.g. within an "async def" expression.

Note that both async for and async with can only be used inside a coroutine function declared with async def.

-- What’s New In Python 3.5

Let's take a closer look at each.

The "async def" Expression

A coroutine can be defined via the "async def" expression.

This is an extension of the "def" expression for defining subroutines.

It defines a coroutine that can be created and returns a coroutine object.

For example:

# define a coroutine
async def custom_coro():
	# ...

A coroutine defined with the "async def" expression is referred to as a "coroutine function"

coroutine function: A function which returns a coroutine object. A coroutine function may be defined with the async def statement, and may contain await, async for, and async with keywords.

-- Python Glossary

A coroutine can then use coroutine-specific expressions within it, such as "async for" and "async with".

Execution of Python coroutines can be suspended and resumed at many points (see coroutine). await expressions, async for and async with can only be used in the body of a coroutine function.

-- Coroutine function definition

You can learn more about defining coroutines in the tutorial:

The "async for" Expression

The "async for" expression is used to traverse an asynchronous iterator.

It is an asynchronous for-loop statement.

An asynchronous iterator is an iterator that yields awaitables.

asynchronous iterator: An object that implements the __aiter__() and __anext__() methods. __anext__ must return an awaitable object. async for resolves the awaitables returned by an asynchronous iterator's __anext__() method until it raises a StopAsyncIteration exception.

-- Python Glossary

The async for expression can be used to traverse an asynchronous iterator within a coroutine.

For example:

...
# traverse an asynchronous iterator
async for item in async_iterator:
	print(item)

This does not execute the for-loop in parallel. The asyncio is unable to execute more than one coroutine at a time within a Python thread.

Instead, this is an asynchronous for-loop.

The difference is that the coroutine that executes the for-loop will suspend and internally await for each awaitable.

Behind the scenes, this may require coroutines to be scheduled and awaited, or tasks to be awaited.

We may also use the async for expression in a list comprehension.

For example:

...
# build a list of results
results = 

This would construct a list of return values from the asynchronous iterator.

You can learn more about the "async for" expression in the tutorial:

The "async with" Expression

The "async with" expression is for creating and using asynchronous context managers.

An asynchronous context manager is a context manager that is able to suspend execution in its enter and exit methods.

-- The async with statement

It is an extension of the "with" expression for use in coroutines within asyncio programs.

The "async with" expression is just like the "with" expression used for context managers, except it allows asynchronous context managers to be used within coroutines.

The async with expression allows a coroutine to create and use an asynchronous version of a context manager.

For example:

...
# create and use an asynchronous context manager
async with AsyncContextManager() as manager:
	# ...

This is equivalent to something like:

...
# create or enter the async context manager
manager = await AsyncContextManager()
try:
	# ...
finally:
	# close or exit the context manager
	await manager.close()

What is Await

Await refers to the "await" expression used with coroutines.

It can only be used within a coroutine and is used to yield execution to an awaitable.

Await expression: Suspend the execution of coroutine on an awaitable object. Can only be used inside a coroutine function.

-- Python Expressions

An awaitable may be another coroutine or a coroutine wrapped in a Task object for independent execution.

An object that can be used in an await expression. Can be a coroutine or an object with an __await__() method.

-- Python Glossary

Put another way, await will cause the caller coroutine to suspend execution at that point and wait for the given awaitable to be done.

The await expression can be used by using the "await" keyword followed by an awaitable.

For example:

...
# await a coroutine
await custom_coroutine()

This line does a few things.

Firstly, it creates a coroutine object.

It then schedules the coroutine for execution in the asyncio event loop.

The caller then suspends execution and waits for the new coroutine to be done.

The awaitable coroutine may return a value that we may want after the awaitable is done.

This can be assigned as part of the await expression.

For example:

...
# await a coroutine and store the return value
value = await custom_coroutine()

You can learn more about the await expression in the tutorial:

Takeaways

You now know the async/await in Python and exactly what it means and when to use it.



If you enjoyed this tutorial, you will love my book: Python Asyncio Jump-Start. It covers everything you need to master the topic with hands-on examples and clear explanations.