Working with async/await in Python

Tutorial 2 of 5

Working with async/await in Python

Introduction

This tutorial aims to provide a comprehensive understanding of the async/await syntax in Python. Through this tutorial, you will learn how to use this syntax to handle asynchronous operations efficiently in Python.

You will learn:

  • The basics of the async/await syntax
  • How to write asynchronous code using async/await
  • Working with asynchronous IO in Python

Prerequisites:

  • Basic understanding of Python programming
  • Familiarity with Python syntax and functions

Step-by-Step Guide

In this section, we will discuss the concepts behind async/await, how it works, and why it is useful in Python programming.

Understanding Async/Await

The async/await syntax is a way of writing concurrent tasks in Python. It is a part of the asyncio library in Python 3.5 and onwards. The async keyword defines a coroutine, which is a special type of function that can be paused and resumed, allowing it to yield control to other tasks.

The await keyword is used to pause execution until the awaited coroutine has finished execution. It can only be used inside an async function.

Writing Asynchronous Code

To write asynchronous code, we define a coroutine using the async def syntax. We can then use the await keyword to pause execution of the coroutine until another coroutine has finished.

async def main():
    print('Hello,')
    await asyncio.sleep(1)
    print('world!')

asyncio.run(main())

In this example, main is a coroutine that first prints 'Hello,', then waits for 1 second before printing 'world!'. The asyncio.run function runs the main coroutine and returns when it is done.

Asynchronous IO

The async/await syntax is especially useful when dealing with IO-bound tasks, such as network requests or file reading/writing. By using async/await, we can start a long-running task and continue with other tasks until it is ready to proceed.

Code Examples

Below are several practical examples of using async/await in Python.

Example 1: Simple Asynchronous Execution

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

asyncio.run(main())

In this example, we define a simple coroutine count that prints "One", waits for one second, and then prints "Two". The main coroutine uses asyncio.gather to run three instances of count concurrently. The asyncio.run function runs the main coroutine.

Example 2: Asynchronous IO

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(html)

asyncio.run(main())

In this example, we use the aiohttp library to perform an async HTTP request. The fetch coroutine takes a session and a URL, makes a GET request to the URL, and returns the response text.

Summary

In this tutorial, we have covered the basics of async/await in Python, how to write asynchronous code using async/await, and how to work with asynchronous IO. To further your knowledge, you can explore other asyncio APIs and third-party libraries that support async/await.

Practice Exercises

  1. Write a coroutine that waits for a random amount of time between 1 and 5 seconds, then prints the amount of time it waited.

  2. Write a coroutine that makes HTTP requests to several URLs concurrently and prints the status code of each response.

  3. Write a program that reads several large files concurrently and prints the number of lines in each file.

Please refer to the Python documentation and the aiohttp documentation for help with these exercises.