Python Requirements: Types, Async, and Await

Python Requirements: Types, Async, and Await

Master the Python 3.8+ features required for FastAPI. Learn about type hints, asynchronous programming, and the event loop.

Python Requirements: The Prerequisites of FastAPI

Before we write app = FastAPI(), we must ensure our Python foundation is solid. FastAPI is what we call a "Type-Hint First" framework. It leverages modern Python features that didn't exist five years ago.

In this lesson, we cover the three pillars of modern Python that make FastAPI possible: Type Hints, Async/Await, and the Event Loop.


1. Type Hints and Annotations

Type hints (introduced in Python 3.5) are the "secret sauce" of FastAPI. They allow you to declare the type of a variable, which FastAPI then uses for data validation and documentation.

Why They Matter in FastAPI:

Without type hints, a web framework has to "guess" if the id in /users/{id} is a string or an integer. With type hints, the instruction is explicit.

# Standard Python
def welcome(name):
    return f"Hello, {name}"

# Modern Python (with Hints)
def welcome(name: str) -> str:
    return f"Hello, {name}"

FastAPI uses these hints to:

  1. Validate: If you say age: int and the user sends "twenty", FastAPI returns an error automatically.
  2. Convert: If the user sends "25", FastAPI converts it to the integer 25 before it reaches your function.
  3. Document: The Swagger UI will show that age must be an integer.

2. Asynchronous Programming: async and await

This is often the most confusing part for developers moving from Flask.

The Mental Model: The Restaurant

  • Synchronous (def): One waiter per table. The waiter takes the order, walks to the kitchen, and stands there staring at the chef until the food is ready. They cannot help any other tables during this time.
  • Asynchronous (async def): One waiter for the whole restaurant. The waiter takes the order, gives it to the kitchen, and immediately goes to help another table. When the kitchen bells ring (the task is done), the waiter comes back to deliver the food.

The Code:

# Sync: Stops the whole program
def fetch_data():
    time.sleep(5)
    return "Data"

# Async: Pauses this function, but the server keeps running
async def fetch_data():
    await asyncio.sleep(5)
    return "Data"

3. The Event Loop

The "Waiter" in our restaurant metaphor is the Event Loop.

The event loop is a continuous loop that checks for tasks that are "ready." When you use the await keyword, you are essentially telling the Event Loop: "I'm going to be waiting for this network request/database query. You can go do other things, and I'll let you know when I'm ready to continue."

When to use async def vs def:

  • Use async def: When your code performs I/O Bound tasks (Database queries, API calls, reading files).
  • Use def: When your code performs CPU Bound tasks (Complex math, image processing, data science calculations). Note: Using async def for CPU-heavy tasks can actually slow down your server because it "blocks" the event loop.

Summary of Python Foundations

FeatureUsed for in FastAPIBenefit
Type HintsValidation & DocumentationAutocomplete & Fewer Bugs
asyncDefining non-blocking endpointsHigh concurrency
awaitPausing execution for I/OEfficient resource use

In the next lesson, we'll apply these to REST API Basics: HTTP Methods, Status Codes, and Headers.


Exercise: Spot the Error

Does the following code leverage the power of FastAPI's async architecture?

import time

@app.get("/slow-report")
async def get_report():
    # Simulate a slow database query
    time.sleep(10) 
    return {"status": "Complete"}

Answer: No! time.sleep() is synchronous and "blocks" the entire thread. Even though the function is labeled async, the event loop is stuck waiting for time.sleep to finish, and no other requests can be handled. You should use await asyncio.sleep(10) instead.

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn