Follow

Follow
asyncio - How to use Async/Await in Python.

asyncio - How to use Async/Await in Python.

Sachin Pal's photo
Sachin Pal
·Feb 1, 2022·

5 min read

Play this article

Table of contents

  • Introduction
  • asyncio - Asynchronous IO :
  • Asynchronous IO :
  • Python's asyncio module :
  • Conclusion

In this article, we gonna discuss how we can use async/await in Python?

Now, if you are familiar with JavaScript then you might know that we use async which makes a function return a promise, and await which makes a function wait for a promise.

We use async and await when we need to fetch some data from the servers to make the execution of the function delay until the promise is resolved and in meantime, the other functions get executed without blocking the other tasks.

This happens because the code is executed asynchronously.

Well, this is not the JavaScript tutorial so we don't dive deep into the working of asynchronous operations in JavaScript.

But I do explain the complete meaning of Asynchronous ahead in this article.

Introduction

Now we gonna discuss how we exactly use async/await in Python?

Just above we encountered the term Asynchronous. What does it mean?

For simple understanding, it just means that not occurring at the same time. It is theoretical meaning. We gonna learn the Practical definition of asynchronous ahead of this article with an example that lets you understand it easily.

Synchronous & Asynchronous Diagram.png

asyncio - Asynchronous IO :

We cannot use async/await syntax directly in the function to make it asynchronous rather we can use a Python package asyncio to achieve the goal.

Before diving into the asyncio module let's understand Asynchronous IO first.

note: I refer to asynchronous IO as async IO and asyncio is a Python package.

Asynchronous IO :

async IO is designed to work on concurrent programming that has received support in Python, from Python 3.4 through Python 3.7 and beyond this.

Let's understand it with the help of an example:

We gonna understand it by the example of a chess master Judit Polgár.

Judit Polgár, a chess master hosts a chess exhibition in which some amateur players took part and she plays with them. She has two ways of conducting the exhibition: synchronously and asynchronously.

Here are the assumptions:

  • There are 24 opponents.
  • Judit makes each chess move in 5 seconds.
  • Opponents each take 55 seconds to make a move.
  • Games average 30 pair moves (60 moves total).

Synchronous approach:

Judit plays one game at a time, never moves to the next game until the current game is completed. Each game takes (55 + 5)* 30 = 1800 seconds or 30 minutes. The entire exhibition takes 24*30 = 720 minutes or 12 hours.

Asynchronous approach:

In this approach, Judit moves table to table, making one move at each table. After making each move she leaves the table and lets the opponent make their next move during the wait time.

One move on all 24 games takes Judit Polgár 24*5 = 120 seconds or 2 minutes. So, the entire exhibition is now cut down to 120*30 = 3600 seconds or just 1 hour.

From the above example, it concludes that async IO tasks that take a long waiting period get blocked and allows other tasks to run during that downtime.

The Source of this example.

Let's move to the next part of this article.

Python's asyncio module :

According to documentation, asyncio is a type of library that helps us to write concurrent code using async/await syntax.

Since it's a module we have to import it.

import asyncio

asyncio works with Coroutines. Coroutines are nothing but a specialized version of Python generator functions.

A coroutine is a function that can suspend its execution before reaching the return and it can indirectly pass the control to another coroutine for some time.

Coroutines declared with the async/await syntax is the preferred way of writing asyncio applications.

Here's the simple use case:

import asyncio

async def func():
    print("Hey....")
    await asyncio.sleep(1)
    print("I am here...")

asyncio.run(func())
  1. async def func() - We used async to make the function asynchronous.

  2. await asyncio.sleep(1) - Here, we used await and used the asyncio.sleep() to delay the execution of print statement below it.

  3. asyncio.run(func()) - Finally we are calling the function. You can see that we used asyncio to call the function, if we try to call the function simply as usual then we get a RuntimeError.

  4. Note: You must be on Python 3.7 or above.

Until here, you surely get some idea on Asynchronous IO and asyncio use case.

Let's look at the examples demonstrating the Asynchronous function:

Asynchronous

import asyncio

async def write():
    print("Hey")
    await asyncio.sleep(1)
    print("there")

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

if __name__ == "__main__":
    import time
    start = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - start
    print(f"File executed in {elapsed:0.2f} seconds")
  1. We created two async functions -

  2. First is the write() function that prints Hey then wait for 1 second and then again prints there.

  3. Second is main() function that executeswrite() function 3 times using asyncio.gather().

  4. And then we wrote a code that calculates the time taken to execute the async functions.

Here's the output:

asyncFirst.png

We can clearly see that the whole code was executed in just 1 second using the asynchronous approach.

What if we execute the same code in Synchronous way:

Synchronous

import time

def write():
    print("Hey")
    time.sleep(1)
    print("there")

def main():
    for _ in range(3):
        write()

if __name__ == "__main__":
    start = time.perf_counter()
    main()
    elapsed = time.perf_counter() - start
    print(f"File executed in {elapsed:0.2f} seconds")

Here's the output:

async2.png

Here, this code snippet took 3 seconds to execute using the synchronous approach.

Now we are clearly able to see the differences in both the approaches and even understand how it's happened.


Conclusion

We can use async/await in Python to make the high-level structured code network for better efficiency.

asyncio is used as a foundation for various Python asynchronous frameworks that provide high-performance networks and web servers, database connection libraries, distributed task queues, etc.


Keep coding✌✌

Did you find this article valuable?

Support Sachin Pal by becoming a sponsor. Any amount is appreciated!

See recent sponsors | Learn more about Hashnode Sponsors
 
Share this