Technology / Programming

How to Create an Async API Call with asyncio

How to Create an Async API Call with asyncio picture: A
Follow us
Published on December 16, 2021

Did you know that Python is considered the most popular programming language of 2021? The Python language has received the most searches in Google and the most job listings thus far this year. That makes sense, considering Python is the most popular programming or scripting language for automation and machine learning, two of the fastest growing IT fields. That means Python is making a lot of API calls. Yet, compared to other programming languages, Python can be much slower at making those API calls.

Why is that?

By design, Python is a blocking language. That means Python code will not be executed until the previous set of instructions has finished. This holds true for definition calls, too.

On the other hand, programming languages like JavaScript are non-blocking languages. That means if a chunk of code is waiting for something to happen, that chunk can release control back to the JavaScript interpreter to do other things. This improves the efficiency of JavaScript considerably. That's because the computer processing the JavaScript code isn't sitting idle. Instead, that computer can use its processor cycles for other chunks of code.

Wouldn't it be nice if Python could use async functions, too?

It turns out that Python can use asynchronous code. Though it might take a little more work to create callbacks in Python than in JavaScript, a library called Asyncio makes writing asynchronous Python code easy. Let's discuss how.

An Overview of How to Create an Async API Call with Asyncio [Video]

In this video, Ben Finkel covers how to create an asynchronous API call in Python. A lot of internet resources have detailed articles that discuss all the ins and outs of synchronous and asynchronous programming, but Ben believes it's more helpful to see it in action and learn how it can improve the responsiveness of your software.

How to Make Async Get Requests in Python?

Python, by design, is a blocking language. That means that it must finish processing lines of code before it can move on to other tasks. This is in stark contrast with languages like JavaScript. Thankfully, with a library called Asyncio, Python can use the same async / await syntax that JavaScript uses to create concurrent code.

Before we go any further, we need to clarify a few things.

First, Asyncio has a lot of different uses. This article is not meant as a full tutorial on how to use all the functions of Asyncio. Instead, it is only meant to demonstrate how to use Asyncio in Python to write concurrent, non-blocking code. If you want to see all the functions that Asyncio can use, it's strongly recommended to read this library's documentation at Python.org.

Second, we provide two Python code examples below. One example is to demonstrate how Python uses async /await calls with Asyncio. We will be referencing this set of example syntax throughout the rest of this article. The other bit of example code demonstrates how a traditional Get request is made in Python using the Requests Python library. Again, we will not reference this set of code. It is only included as an example to compare against what asynchronous code looks like in Python.

Third, since we will be referencing the asynchronous code throughout this article, we will include reference comments in the code example below. For instance, we may refer to 'Reference 1 in the code example.' Therefore, we will notate Reference 1 with a comment in the example code ( # Reference 1).

Fourth, examine the asynchronous Python code example closely. You'll notice the first function is called 'count()' located at Reference 1 in the code example. We won't discuss this function at all other than to say its goal is to count once a second and then display that count in the console. This function serves as a visual example if you want to see how asynchronous Python code works. Feel free to copy and run that asynchronous Python code example below. What do you think will happen? When will the response to 'get_delay()' be displayed in the console?

How to Install Asyncio in Python

Before you can make async and await calls in Python, you need to install the Asyncio library in your Python environment. This can be done with Python's Pip package manager.

pip install asyncio

That will enable Asyncio to be available in your Python projects going forward.

Next, you need to import the Asyncio library into your Python code (Reference 2 in the example below).

import asyncio

Finally, for the purposes of this article, we are going to use the ClientSession function from the Aiohttp class code (Reference 3 in the example below).

from aiohttp import ClientSession

Aiohttp is an asynchronous HTTP client and server package for Python using Asyncio. If you are familiar with Express for NodeJS, you will feel very comfortable with Aiohttp. Because Aiohttp is a separate package from Asyncio, it must also be installed through the Pip package manager. Use the same Pip install command above but replace 'asyncio' with 'aiohttp.'

How to Make Async Get requests in Python with Aiohttp

Before using Aiohttp to perform Get requests in Python, make sure to have the Asyncio library installed and imported into your Python project first. Aiohttp is an HTTP client and server for Python. It depends on Asyncio due to the asynchronous nature of HTTP Get requests.

Using Aiohttp to make Get requests depends on the async and await features of the Asyncio library. This is very similar to JavaScript. Because asynchronous operations in Python are not built-in and depend on the Asyncio library, we need to first call a function of the Asyncio library to kick off the asynchronous code operations (Reference 4 in the example below).

asyncio.run(main())

Asyncio leverages the blocking nature of Python to function. Basically, this function call is calling another function. This second function (Reference 5 in the example below) is what we then use to call the rest of our asynchronous functions.

async def main(): 
      await asynchio.gather(get_delay(5),count())

The 'main()' function uses another function of Asyncio to call both the 'get_delay()' and 'count()' functions.

This might seem like a lot of work just to call a couple of functions asynchronously. This is required due to how Python is designed, though. Because Python is blocking by nature, we need to call a single function that will be used to start the asynchronous code process.

Any functions that are not async / await functions will not be processed until after the 'asyncio.run(main())' call is made. So, for instance, if you had another function after 'asyncio.run(main())' that adds two numbers together (Reference 6 in the example below), that function won't run until after all of the other async /await functions finish from 'asyncio.run(main())'.

Here’s another way to visualize how async code runs in Python:

  1. Asyncio.run calls the 'main()' function.

  2. 'main()' calls both 'get_delay()' and 'count()'

  3. Both 'get_delay()' and 'count()' process their code at the same time but independent of each other

  4. Both 'get_delay()' and 'count()' finishes processing and returns priority back to 'main().'

  5. 'main()' is now finished, so it returns priority back to asyncio.run.

  6. asyncio.run is now finished, so the rest of the code runs (otherwise, the 'addTwoNumbers()' finally executes).

Let's ignore the 'count()' function and focus on the 'get_delay()' function. The 'get_delay()' function is not complicated. Let's walk through it.

First, this function defines the endpoint for the API it wants to call. Then it prints some text to the console. That text isn't important. It's only meant as a visual queue that the 'get_delay()' function is working.

Next, we make an async call using the 'ClientSession()' method from that Aiohttp library. We design the object from 'ClientSession()' simply as 'session.'

Inside that asynchronous call, we set the variable’s value called 'response' to the actual response of the HTTP Get request that was made by 'session.read()'. The 'session.read()' function knows what HTTP API URL and endpoint to use when we define 'session' using 'ClientSession().'

Once the 'session.read()' receives a message back from 'http://httpbin.org/delay/5', it assigns that message to 'response.' Then 'response' is printed to the console.

All of this is happening while 'count()' is processing and outputting its count to the console as well.

from aiohttp import ClientSession
 base_url = 'http://httpbin.org'
 async def count()
  for I in [1,2,3,4,5]:
  print(i)
  await asyncio.sleep(1)
 async def get_delay(seconds)
  endpoint = f'/delay/{seconds}'
  print(f'Getting with {seconds} delay … ')
  async with ClienSession(base_url+endpoint) as session:
   response = await response.read()
   print(response)
 async def main():
  await asynchio.gather(get_delay(5),count())
 asyncio.run(main())
 def addTwoNumbers (x, y):
  print(x + y)
 addTwoNumbers (2, 5)
 print('Okay! All finished getting.')
base_url = 'http://httpbin.org/'
def get_delay(seconds):
 endpoint = f'/delay/{seconds}'
 print(f'Getting with {seconds} delay … ')
 resp = requests.get(base_url+endpoint)
 data = resp.json()
 print(data)
get_delay(5)
print('Okay! All finished getting.')

Wrapping Up

We covered a lot of information in that video! We barely scratched the surface of async operations in Python, or for that matter, Python in general, in this article, though. If you want to learn more Python, consider taking an Automation with Python course.

Let's recap what we talked about. Python is a blocking programming language by design. Unfortunately, it doesn't understand the concept of asynchronous code. We can write asynchronous code with Python by using a library called Asyncio, though.

Python has another library called Aiohttp that is an HTTP client and server based on Asyncio. Thus, we can use Asyncio to create asynchronous API calls.

This is useful for optimizing code. Because Python is a blocking language, it is possible to cause idle time waiting for Python to finish tasks (like waiting for API calls). By using asynchronous code, we can keep Python constantly working without any idle time.


Download

By submitting this form you agree to receive marketing emails from CBT Nuggets and that you have read, understood and are able to consent to our privacy policy.


Don't miss out!Get great content
delivered to your inbox.

By submitting this form you agree to receive marketing emails from CBT Nuggets and that you have read, understood and are able to consent to our privacy policy.

Recommended Articles

Get CBT Nuggets IT training news and resources

I have read and understood the privacy policy and am able to consent to it.

© 2024 CBT Nuggets. All rights reserved.Terms | Privacy Policy | Accessibility | Sitemap | 2850 Crescent Avenue, Eugene, OR 97408 | 541-284-5522