6_FastAPI Notes
FastAPI
- FastAPI is a modern, high-performance web framework for building APIs with Python 3.7+.
- It is based on standard Python type hints.
- Designed for speed in both execution and development.
Key Features of FastAPI
- Fast: High performance, comparable to NodeJS and Go, thanks to Starlette and Pydantic.
- Easy to use: Intuitive design reducing bugs, with automatic data validation and interactive documentation.
- Type-hinting support: Uses Python type hints for request parameters and JSON bodies.
- Auto-generated documentation: Swagger UI and ReDoc are automatically generated.
- Asynchronous support: Built with async/await for non-blocking code.
- Data validation: Uses Pydantic models to enforce and validate data formats.
FastAPI vs Flask
| Feature | FastAPI | Flask |
|---|---|---|
| Created for | Modern, async, high-performance APIs | Simplicity and flexibility, general web apps |
| Python version | Python 3.7+ (requires type hints) | Python 2.7+ / 3.x (more broadly compatible) |
| Async support | Native async/await support | Not natively - needs workarounds or extensions |
| Performance | Very fast (Starlette + async) | Slower (sync only by default) |
| Type Hints | First-class citizens - used for validation/docs | Optional, not integrated |
| Data validation | Built-in (Pydantic models) | Manual or with marshmallow/wtforms |
| Automatic docs | Swagger & ReDoc auto-generated | Not built-in (needs Flask-RESTPlus or similar) |
| Best for | APIs, microservices, async-heavy apps | Simple web apps, quick scripts, classic MVC |
FastAPI vs REST
- FastAPI is a web framework known for speed and automatic documentation.
- FastAPI helps build APIs that often follow RESTful principles.
- FastAPI uses Python type hints for data validation and serialization.
- It supports asynchronous programming for high performance.
- REST is an architectural style for designing networked applications.
- REST defines resource structure and access over HTTP, but doesn’t enforce specific implementation.
- RESTful APIs can be asynchronous depending on the framework.
FastAPI vs Flask Code Examples
FastAPI
from fastapi import FastAPI app = FastAPI() @app.get("/hello") def read_hello(name: str): return {"message": f"Hello {name}"}Flask
from flask import Flask, request app = Flask(__name__) @app.route("/hello") def read_hello(): name = request.args.get("name") return {"message": f"Hello {name}"}
Requirements
- Python 3.7+ (Python 3.11+ recommended)
- pip for installing packages
- Optional: virtual environment for dependency isolation
- A code editor (e.g., VS Code)
Installation
Install FastAPI and Uvicorn:
pip install fastapi uvicorn
Uvicorn
- Uvicorn is a lightweight ASGI server for running asynchronous Python web apps like those built with FastAPI.
- FastAPI handles logic and routing.
- Uvicorn handles communication between users and the app.
- It listens for incoming requests, passes them to FastAPI, and sends responses back.
ASGI
- Uvicorn is built on ASGI (Asynchronous Server Gateway Interface).
- ASGI is a newer, powerful alternative to WSGI.
ASGI Features:
- Async code (non-blocking)
- WebSockets support
- Better performance under load
Why use Uvicorn with FastAPI?
- FastAPI is async-friendly and built for ASGI.
- Uvicorn is a popular ASGI server.
- It’s fast and production-ready.
Type Hints
- Type hints specify expected data types for variables, function parameters, and return values using Python’s type annotations.
- FastAPI relies on type hints to validate, serialize, and generate documentation.
Why Type Hints Matter in FastAPI
- Validate request data (e.g., query parameters, path parameters, body data).
- Generate automatic OpenAPI documentation.
- Improve editor support (e.g., auto-completion, linting).
- Deserialize and serialize data properly.
Data Types
str: Represents a string of text.int: Represents an integer number.float: Represents a decimal or floating-point number.bool: Represents a boolean value (TrueorFalse).Optional[X]: Indicates a value that can be of typeXorNone.List[X]: A list containing items of typeX.Dict[K, V]: A dictionary with keys of typeKand values of typeV.Union[X, Y]: A value that can be of typeXorY.BaseModel: A Pydantic model used for structured request or response bodies.
Example: Query Parameters
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
def read_item(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
Example: Path Parameters
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
Example: Body Parameters with Pydantic
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class Product(BaseModel):
name: str
price: float
tags: list[str]
in_stock: bool
@app.post("/products/")
def create_product(product: Product):
return {"product": product}
Async
- You can define endpoint functions using
async defto handle multiple requests asynchronously. async defdeclares an asynchronous function.- Lets your app pause while waiting (e.g., for a database call), so other requests can be served in the meantime.
- Great for I/O-bound operations (like calling APIs, databases, etc.).
- Synchronous (
def) functions block the app until finished. - Asynchronous (
async def) functions don't block—they can "pause" and let other tasks run while waiting.
Example:
from fastapi import FastAPI
from pydantic import BaseModel
import asyncio # Optional: to simulate delay
app = FastAPI()
# Pydantic model for POST body
class Item(BaseModel):
name: str
price: float
# Async GET endpoint
@app.get("/ping")
async def ping():
await asyncio.sleep(1) # Simulates a delay, like calling a database
return {"message": "pong"}
# Async POST endpoint
@app.post("/items/")
async def create_item(item: Item):
await asyncio.sleep(1) # Simulates some processing delay
return item
Task
- A task refers to an asynchronous operation or background task that is executed without blocking the main thread or process.
- Allows the application to continue handling other requests.
- FastAPI provides built-in support for asynchronous tasks via Python's
asynciolibrary. - Tasks are used for background jobs, scheduled tasks, or time-consuming operations outside of the request-response cycle.
1. Background Tasks in FastAPI
- FastAPI has a feature called Background Tasks to run code in the background without delaying the response.
- Useful for tasks like sending emails, logging, or processing large amounts of data, while giving the user an immediate response.
2. Asynchronous Tasks with async/await
- FastAPI supports asynchronous operations using Python’s
asyncandawaitsyntax. - When you define an endpoint with
async def, the handler function can perform asynchronous tasks without blocking the main thread. - Examples: making HTTP requests, querying a database, or performing file I/O operations.
3. Using Task Queues (e.g., Celery)
- For more complex background task handling, use a task queue like Celery.
- Celery allows you to distribute tasks across workers, retry tasks on failure, and manage task results.
- FastAPI can be integrated with Celery for task processing.
Validation
- FastAPI uses Pydantic models for request body validation, query parameters, and more.
- It automatically validates the incoming data and gives meaningful error messages.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = False # Optional with default
@app.post("/items/")
async def create_item(item: Item):
return {"item": item}
- If a client sends invalid JSON (e.g., missing fields or wrong types), FastAPI will return a 422 Unprocessable Entity response with a structured error.
Error Handling
- You can handle errors globally using exception handlers.
- FastAPI gives you built-in exceptions like
HTTPException, and you can create custom ones too.
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id != 42:
raise HTTPException(status_code=404, detail="Item not found")
return {"item_id": item_id}