DeployU
Interviews / Backend Engineering / How do you use the `asyncio` module to write concurrent code in Python?

How do you use the `asyncio` module to write concurrent code in Python?

practical Concurrency Interactive Quiz Code Examples

The Scenario

You are a backend engineer at a social media company. You are writing a new service that needs to make a large number of concurrent I/O operations, such as making HTTP requests to other services and querying a database.

You know that you should not perform these operations synchronously, because it will block the event loop. You are considering using the asyncio module to write concurrent code.

The Challenge

Explain how you would use the asyncio module to write concurrent code in Python. What are the key concepts of asyncio, and how would you use them to solve this problem?

Wrong Approach

A junior engineer might try to solve this problem by using multi-threading. This would not be a good solution, because of the GIL. They might also not be aware of the `asyncio` module or the `async` and `await` keywords.

Right Approach

A senior engineer would know that `asyncio` is the perfect tool for this job. They would be able to explain the key concepts of `asyncio`, and they would have a clear plan for how to use it to write concurrent code.

Step 1: Understand the Key Concepts of asyncio

ConceptDescription
async/awaitThe async and await keywords are used to define and call coroutines.
CoroutineA coroutine is a function that can be paused and resumed.
Event LoopThe event loop is the core of every asyncio application. It runs asynchronous tasks and callbacks, performs network IO operations, and runs subprocesses.
TaskA task is a coroutine that is scheduled to run on the event loop.

Step 2: Write a Simple asyncio Program

Here’s how we can write a simple asyncio program to make two concurrent HTTP requests:

import asyncio
import aiohttp

async def main():
    async with aiohttp.ClientSession() as session:
        task1 = asyncio.create_task(session.get('http://python.org'))
        task2 = asyncio.create_task(session.get('http://google.com'))

        responses = await asyncio.gather(task1, task2)

        print(responses[0].status)
        print(responses[1].status)

asyncio.run(main())

In this example, we use asyncio.create_task() to schedule the two HTTP requests to run on the event loop. We then use asyncio.gather() to wait for both requests to complete.

The Benefits of Using asyncio

BenefitDescription
Concurrencyasyncio allows you to write concurrent code that can handle a large number of I/O operations.
Performanceasyncio can be very performant, especially for I/O-bound tasks.
ReadabilityThe async and await keywords make it easy to write asynchronous code that is readable and maintainable.

Practice Question

You want to run a CPU-intensive operation in the background without blocking the event loop. Which of the following would you use?