← Back to Chapters

FastAPI Tutorial

? FastAPI Tutorial

⚡ Quick Overview

FastAPI is a modern, fast (high-performance) web framework for building APIs with Python 3.7+. It is built on top of Starlette (for web parts) and Pydantic (for data validation), and uses standard Python type hints to automatically generate:

  • ? Auto routes – Define endpoints using simple decorators.
  • ? OpenAPI docs – Interactive Swagger UI at /docs.
  • ✅ Validation – Request/response validation via Pydantic models.
  • ⚙️ Async support – Built-in async/await support for concurrency.

? Key Concepts

  • FastAPI application object – Created using FastAPI().
  • Path operation – A function mapped to an HTTP method and path using decorators like @app.get(), @app.post(), etc.
  • Path parameters – Values embedded in the URL path.
  • Query parameters – Key-value pairs after ? in the URL.
  • Request body – Data sent in the body (usually JSON), validated via Pydantic models.
  • Response model – Type-hint or Pydantic model that shapes the output JSON.
  • Automatic docs – Swagger UI at /docs, ReDoc at /redoc.

? Syntax and Core Ideas

A minimal FastAPI application follows these steps:

  1. Install FastAPI and an ASGI server such as Uvicorn.
  2. Create a Python file (for example, main.py).
  3. Create a FastAPI instance.
  4. Define path operations using decorators (@app.get(), @app.post(), etc.).
  5. Run the app using Uvicorn.
? View Basic FastAPI App
# Install (run in terminal)
# pip install "fastapi[all]" uvicorn

from fastapi import FastAPI

# Create application instance
app = FastAPI()

# Define a path operation (GET /)
@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

# Define a path operation with path parameter
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "query": q}

# Run the server from terminal:
# uvicorn main:app --reload

? Request Body and Pydantic Models

To receive structured JSON from the client, you define a Pydantic model. FastAPI automatically:

  • Parses JSON into the model.
  • Validates types (e.g., int, float, str).
  • Documents the schema in the OpenAPI docs.
? View Example: POST with Request Body
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# Define a Pydantic model
class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    in_stock: bool = True

# POST endpoint to create an item
@app.post("/items/")
def create_item(item: Item):
    # item is automatically validated and converted to a Python object
    tax = item.price * 0.18
    total = item.price + tax
    return {
        "item": item,
        "tax": tax,
        "total_price": total
    }

? Live Output and Explanation

? Sample Request

Send a POST request to http://127.0.0.1:8000/items/ with JSON:

{
  "name": "Laptop",
  "description": "Fast developer machine",
  "price": 60000,
  "in_stock": true
}

FastAPI will:

  • Validate the fields (type, required vs optional).
  • Call create_item() with an Item instance.
  • Return a JSON response with the original data plus calculated tax and total price.

Expected response (simplified):

{
  "item": {
    "name": "Laptop",
    "description": "Fast developer machine",
    "price": 60000.0,
    "in_stock": true
  },
  "tax": 10800.0,
  "total_price": 70800.0
}

? Use Cases

  • RESTful APIs for web or mobile applications.
  • Microservices that require high performance and low latency.
  • Machine learning model serving and data APIs.
  • Internal tooling dashboards / automation services.

?️ Path and Query Parameters

FastAPI uses function parameters to detect where data should come from:

  • Parameters in the decorator path "/items/{item_id}" are path parameters.
  • Extra function parameters with default values are treated as query parameters.
? View Example: Path and Query
# Path and query parameters example
from fastapi import FastAPI

# Create FastAPI application
app = FastAPI()

# Endpoint with path and query parameters
@app.get("/users/{user_id}")
def get_user(user_id: int, active: bool = True):
    """
    Example URL:
    /users/10?active=false
    """
    return {
        "user_id": user_id,
        "active": active
    }

? Tips and Best Practices

✅ Best Practices

  • Keep your project structured (separate routers, models, schemas, services).
  • Use type hints everywhere – FastAPI depends on them for validation and docs.
  • Use Pydantic models both for request and response to keep contracts clear.
  • Use uvicorn main:app --reload during development for auto-reload.
  • Secure APIs using dependencies for authentication and authorization.
  • Document commonly used responses and error formats with responses parameter.

? Practice Tasks

  1. Create a FastAPI project with endpoints:
    • GET / returning a welcome message.
    • GET /square/{number} returning the square of a number.
  2. Define a Pydantic model Student with fields id, name, and marks. Create a POST /students/ endpoint that accepts and returns a student object.
  3. Add a query parameter min_marks to filter students by minimum marks.
  4. Open /docs in your browser and test all endpoints using the auto-generated Swagger UI.
  5. As a challenge, add a simple in-memory list to store created students and implement GET /students/ to return them.

? Interactive Docs

Once your FastAPI app is running, open the following URLs in your browser:

  • http://127.0.0.1:8000/docs – Swagger UI (interactive docs).
  • http://127.0.0.1:8000/redoc – ReDoc alternative documentation.

You can send requests directly from these UIs without writing a separate client.