Asynchronous programming in Python
Bruno
Posted on March 22, 2023
Have you ever wanted to learn how to write asynchronous code, but found it difficult to understand how it all works and how to apply it in Python? Well, let me tell you it is not as difficult as it seems. Just bear with me as we go through the different sides of the pyramid.
🤔 What is asynchronous programming? And how does it differ from synchronous programming?
When we write code, it is typically executed one line at a time, in the sequence in which it was written. This is referred to as synchronous programming. However, there are occasions when we must execute lengthy activities, such as reading data from a file, fetching information from a remote server or API endpoint, or waiting for user input.
Asynchronous programming, on the other hand, allows us to perform these long-running tasks without blocking the rest of our code from executing. Instead of waiting for a task to complete before moving on, we can start the task and then move on to the next line of code. When the task is finished, we can come back to it and continue where we left off.
🐍 Asynchronour programing in Python
In Python, we can write asynchronous programming using external libraries such as asyncio
, which I will be using throughout this article.
In order to use asyncio
, you need to install (if you are using a version pre-3.7) and import it to your Python project:
- Installing
asyncio
:
pip install asyncio
- Importing
asyncio
:
import asyncio
Now you should be able to use asyncio
and all its available functions/methods in your project 🎉
⚙️ Coroutines
A coroutine
is a function that can be paused and resumed during execution.
You define a coroutine
using the async
keyword.
Take the following example:
async def my_coroutine():
print("Coroutine started")
await asyncio.sleep(1)
print("Coroutine resumed")
In the example above, the coroutine function runs in the following order:
- runs
print("Coroutine started")
- waits (with
await
) for 1 second until it can resume - runs
print("Coroutine resumed)
🔂 Creating an event loop
In order to run coroutines concurrently, you need to use an event loop. It can manage multiple coroutines at the same time and you can use the asyncio.get_event_loop()
method from the asyncio
library for that purpose:
async def coroutine_one():
print("Coroutine started")
await asyncio.sleep(1)
print("Coroutine resumed")
async def coroutine_two():
print("Coroutine two started")
await asyncio.sleep(2)
print("Coroutine two resumed")
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine_one(), coroutine_two())
The code above runs in the following order:
-
coroutine_one
is executed -
print("Coroutine started")
prints a message stating thecoroutine
has started -
await asyncio.sleep(1)
waits for 1 second until it resumes the execution ofcoroutine_one
-
print("Coroutine resumed")
prints a message stating thecoroutine
has resumed -
coroutine_two
is executed -
print("Coroutine started")
prints a message stating thecoroutine
has started -
await asyncio.sleep(2)
waits for 2 seconds until it resumes the execution ofcoroutine_two
-
print("Coroutine resumed")
prints a message stating thecoroutine
has resumed -
main()
function is define and is used to run both coroutines concurrently - simultaneously - an
event loop
is created usingloop = asyncio.get_event_loop()
-
loop
is executed onloop.run_until_complete(coroutine_one(), coroutine_two())
-
coroutine_one()
is executed and runsprint("Coroutine started")
-
coroutine_two()
is executed and runsprint("Coroutine started")
-
coroutine_one()
waits for 1 second until it can resume -
coroutine_two()
waits for 2 seconds until it can resume - after both coroutines wait for 1 and 2 seconds to resume,
loop
finishes executing and returns the results of the loop
🛰 Using async/await with external libraries
Imagine you want to work with HTTP requests asynchronously, you can make use of the async
and await
keywords to make those requests in an asynchronous programming manner. Take the example of the aiohttp
library:
import asyncio
import aiohttp
async def get_data():
async with aiohttp.ClientSession as session:
async with session.get(url) as response:
data = response.json()
return await data
async def main():
data = await get_data("catsjsonapi.com/cat1")
print(data)
loop = async.get_event_loop()
loop.run_until_complete(main())
In this example, we are importing the asyncio
and aiohttp
libraries to make HTTP requests asynchronously. As an overview if the code above, the main()
coroutine is executed using loop
(the event loop), which executes the get_data()
coroutine and then prints the data from the "catsjsonapi.com/cat1"
API endpoint as JSON.
💭 Final thoughts
Working with asynchronous programming in Python can be very useful in various environments/projects, and doing so is quite easy, as we saw throughout this article. All you need to do is import asyncio
and make use of its functions, combine with external libraries, and so on.
However, there are other libraries which allow you to write asynchronous code in Python, such as:
- Trio: https://trio.readthedocs.io/en/stable/
- Trio-asyncio: https://trio-asyncio.readthedocs.io/en/latest/
Thank you for reading!👋
After having gone through all of these bits and bytes of async programming in Python, you should now be able to apply it in your code. Congratulations 🙌 and I hope it was helpful for you!🙂
I'd like to thank you for reading my article and invite you to follow me on Dev.to, as well as my other platforms:
GitHub: https://github.com/bcostaaa01
Twitter: https://twitter.com/bruno2001costa
I look forward to seeing you on my next one!
Until then,
Happy Coding!👩💻
Posted on March 22, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.