Table of contents
No headings in the article.
Python's async/await syntax, introduced in Python 3.5, simplifies the creation of asynchronous code by allowing non-blocking code execution that can perform multiple tasks concurrently without the need for callbacks or threads. FastAPI, a popular web framework for building APIs in Python, leverages async/await heavily to achieve high performance and scalability.
Async/await involves creating and running coroutines that can be paused and resumed, permitting other code to run in between. The event loop can execute other coroutines waiting for I/O operations or other tasks while a coroutine is paused. For instance, the following example showcases a coroutine that employs async/await syntax:
async def my_coroutine():
print("Starting coroutine")
await asyncio.sleep(1)
print("Coroutine resumed")
The async
keyword declares my_coroutine
as a coroutine function, while await
pauses the coroutine and waits for another coroutine or Future to finish. In the example, asyncio.sleep
pauses the coroutine for one second.
To run the coroutine, we require an event loop. Here's an example of how to execute my_coroutine
with the asyncio event loop:
import asyncio
async def main():
coro = my_coroutine()
await coro
asyncio.run(main())
In this example, main
is another coroutine that creates an instance of my_coroutine
and then awaits it. We can execute the main
coroutine using the default event loop with asyncio.run
.
FastAPI enables us to define asynchronous endpoints easily with the async def
syntax. The Starlette web framework, upon which FastAPI is built, utilizes async/await extensively to achieve high performance and scalability. For instance, the following example defines a FastAPI app with a single asynchronous endpoint that returns a JSON message:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
In this example, the async
keyword denotes that root
is a coroutine that can be paused and resumed. We can run the app using the uvicorn
server:
$ uvicorn main:app --reload
When we send a request to http://localhost:8000/
, FastAPI runs the root
coroutine and returns the JSON message.
We can perform I/O operations asynchronously within our endpoints using async/await, such as making an asynchronous HTTP request to another API. Here's an example of how to do that in FastAPI:
import httpx
@app.get("/async")
async def async_endpoint():
async with httpx.AsyncClient() as client:
response = await client.get("https://example.com")
return {"message": response.text}
In this example, async_endpoint
is another endpoint that makes an asynchronous HTTP request to https://example.com
using httpx
.