The web content provides a comprehensive guide on implementing asynchronous requests in Flask 2.0 using the Httpx library, emphasizing the benefits of asyncio for handling I/O-bound tasks more efficiently.
Abstract
The article titled "Getting started with Async requests in Flask using Httpx" introduces the new capabilities of Flask 2.0 for handling asynchronous routes, which is a significant update from previous versions. It delves into the use of asyncio and the aiohttp library to manage asynchronous operations, demonstrating how these tools can improve the performance of I/O-bound tasks such as fetching data from APIs. The author illustrates the concept with a practical example of a Flask application that fetches images from the xkcd comic API, comparing the performance of synchronous versus asynchronous requests. The article also discusses the prerequisites for using asyncio in Flask, the implementation of async routes, and the use of the Httpx library for making asynchronous HTTP requests. The conclusion highlights the potential use cases for async requests in Flask applications and suggests that developers can leverage these new features without necessarily migrating to other frameworks like FastAPI or Quart.
Opinions
The author believes that the new async features in Flask 2.0 are a significant improvement, making it a viable option for developers who might otherwise consider migrating to other async-capable frameworks.
There is an emphasis on the efficiency gains from using asyncio, particularly for I/O-bound tasks, suggesting that it can lead to better resource utilization and reduced latency in web applications.
The author promotes the Httpx library as a suitable tool for making asynchronous HTTP requests in Flask, implying that it integrates well with the async features of the framework.
The article implies that the ability to handle multiple I/O tasks concurrently without blocking the main thread is a key advantage of async programming in Flask.
The author encourages readers to explore more about Flask 2.0's updates and to consider a Medium membership to support writers and access unlimited stories.
Getting started with Async requests in Flask using Httpx
Recently Flask has introduced async routes in its 2.0 update. This blog is everything about async requests with Flask 2.0. The Flask 2.0 has come up with many interesting updates. Do check out this blog of Progress Story for all the updates of Flask 2.0. In this blog, we will be going to learn something about asyncio, aiohttp and async routes of Flask.
Agenda
We will be covering the below topics in this blog
async/await | Asyncio
Async routes in Flask
Benchmarking
Async requests with Asyncio — async/await
Asyncio is a library to write concurrent code using the async/await syntax. It is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web servers, database connection libraries, distributed task queues, etc.
It is often a perfect fit for IO-bound and high-level structured network code.
Using Python asyncio , we can also make better use of the CPU sitting idle when waiting for the I/O. asyncio is single-process and single-thread. There is an event loop in asyncio , which routinely measure the progress of the tasks.
If the event loop has measured any progress, it would schedule another task for execution, therefore, minimizing the time spent on waiting for I/O. This is also called cooperative multitasking. The tasks must cooperate by announcing when they are ready to be switched out. And the announcement is explicitly made by await keyword.
Async in Flask 2.0
Let’s create a simple Flask application that is having a route that calls some URL and fetches the result synchronously. For that, we would need to install flask and requests a library
pip install flask
pip install requests
To make it interactive we will be using the xkcd comic images. If you haven’t heard about this, then do check out what xkcd comic is.
Now let’s create an API comic that will render a random page of xkcd comic using the requests library
Output:
To fetch one page from the comic book it took around 1 sec. Let’s say we want to fetch 5 pages from a comic book, then it will take approximately around 5 secs.
Output
Flask application is fetching 5 images from xkcd comic synchronously. Initially, it fetches the first image and waits for the response and doing nothing at that time. Then once the response is received then it again fetches the second image and doing nothing at that time. This task is an I/O bound task where the CPU is sitting idle doing nothing and waiting for the result of the I/O task, in this case, it is an API call.
This problem can be solved with multithreading and asyncio. In this blog, we will learn how we can solve this using asyncio in Flask. Let’s modify our existing code a bit.
For asyncio to work in the flask, we must satisfy the prerequisites.
python version > 3.6
Remove all blocking code inside the route
pip install"Flask[async]"
pip install httpx
Implementation of async requests
For async routes in flask 2.0 just use the below syntax
@app.get('/comic')asyncdefhello():
pass
Now we want to call multiple times API but all in an asynchronous fashion. At present, the requests library is not able to do that. So for that, we will install the httpx library and convert the code like below
asyncdefget_multiple_images(number):
asyncwith httpx.AsyncClient() as session: # asynclient will work with async
tasks = [get_xkcd_image(session) for _ inrange(number)]
result = await asyncio.gather(*tasks, return_exceptions=True) # will use gather to run every coroutine asynchronously and gather the result in ordered fashionreturn result
Convert the API request to a coroutine
async def get_xkcd_image(session):
random = randint(0, 300)
result = await session.get(f'http://xkcd.com/{random}/info.0.json') # create awaitable objectofsessionget so that at this point, thread will not wait for the result insteadof it it will do a context switch to other part of program
return result.json()['img']
Put await before the actual call to third party API. By using await it will not wait for the result of the third party API call. Instead, it will do the context switching to other parts of the program.
The new code will look like below.
Now the output will is taking 1 sec
Async requests with flask | Async requests with Flask
It seems all 5 requests were called at the same time as previously it was taking around 5 seconds to complete all the requests but not it took only 1 second to complete all the requests.
asyncio lifecycle | Async requests with Flask
Use Cases of async requests in Flask
Async requests are getting popular day by day because of the simplicity and reducing the time consuming I/O tasks. If the flask application is calling other microservices or doing some other I/O tasks. Then the async routes will be of much help by utilizing the CPU process and thread to the fullest.
For example, when a single route is calling more than 1 third party API or other microservices APIs then, don’t need to call them synchronously and wait for the results. Instead, just call them asynchronously and serve the result to the front end.
Conclusion
FastAPI/Quart are well known for the async routes frameworks. If you are considering migrating from flask to these frameworks just for this reason then, I guess it’s time to use Flask to the fullest.
See you next time! Peace Out ✌️
If you liked this story, you might also like a Medium membership. It’s only $5 a month (a price of a cup of coffee!) but it will give you unlimited access to stories while supporting your favourite writers. If you sign up using this link, I’ll earn a small commission, isn’t it sweet. Thanks!