Sunday, 23 November 2025

All in One - Hands-On!?!

FastAPI 12-Module Hands-On Worksheet — Full Course (Single Page)

FastAPI — 12 Module Hands-On Worksheet (Complete)

Student labs, step-by-step tasks, assessments, instructor answers & final project — single page.
Ready to paste into Blogger → Compose or HTML view

Quick Start (For Instructors)

Use this single page during a lab session. Each module contains: learning outcomes, step-by-step lab, practice questions and a mini assignment.

# Quick environment (one-time)
python -m venv .venv
# Linux/macOS
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1

pip install fastapi uvicorn sqlalchemy pydantic psycopg2-binary alembic
        

Module 1 — Introduction & Setup

Learning outcomes: install FastAPI, run first endpoint, explore /docs.

Lab Steps

  1. Create main.py with this code.
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def home():
    return {"message": "Hello FastAPI"}
        

Test

Run: uvicorn main:app --reload → Open http://127.0.0.1:8000/docs

Practice

Create an endpoint /hello/{name} to return student name.

Module 2 — Path & Query Parameters

Outcome: dynamic routes, optional params, validation via type hints.

from fastapi import FastAPI
from typing import Optional

app = FastAPI()

@app.get("/items/{item_id}")
def get_item(item_id: int):
    return {"item_id": item_id}

@app.get("/search")
def search(q: Optional[str] = None, limit: int = 10):
    return {"q": q, "limit": limit}
        

Practice

Try: /items/5 and /search?q=fastapi&limit=3

Module 3 — Pydantic Models

Outcome: request body validation, correct types & defaults.

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float
    description: str | None = None
    in_stock: bool = True

app = FastAPI()

@app.post("/items/")
def create_item(item: Item):
    return item
        

Mini Assignment

Add a field category: str and make it optional.

Module 4 — In-Memory CRUD

Outcome: implement POST/GET/PUT/DELETE against a Python list.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List

class Item(BaseModel):
    name: str
    price: float

app = FastAPI()

items_db: List[Item] = []

@app.post("/items/", response_model=Item)
def create_item(item: Item):
    items_db.append(item)
    return item

@app.get("/items/", response_model=List[Item])
def list_items():
    return items_db

@app.get("/items/{item_id}", response_model=Item)
def get_item(item_id: int):
    if item_id >= len(items_db):
        raise HTTPException(status_code=404, detail="Item not found")
    return items_db[item_id]

@app.put("/items/{item_id}", response_model=Item)
def update_item(item_id: int, updated: Item):
    if item_id >= len(items_db):
        raise HTTPException(status_code=404, detail="Item not found")
    items_db[item_id] = updated
    return updated

@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    if item_id >= len(items_db):
        raise HTTPException(status_code=404, detail="Item not found")
    items_db.pop(item_id)
    return {"message":"deleted"}
        

Practice

Use the Swagger UI to create multiple items and update/delete them.

Module 5 — Routers & Project Structure

Outcome: split app using APIRouter, modular code.

Steps

  1. Create routers/items.py with an APIRouter, then include it in main via app.include_router().
Mini assignment: create routers/users.py and a simple register route.

Module 6 — SQLAlchemy ORM & Models

Outcome: create ORM models and connect via SQLAlchemy.

# database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base

DATABASE_URL = "postgresql://postgres:postgres@localhost/fastapi_db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
Base = declarative_base()
        
Mini assignment: add a column rating: int to the model and migrate.

Module 7 — PostgreSQL CRUD (Sync SQLAlchemy)

Outcome: perform real DB CRUD, use session dependency.

# crud.py (example functions)
from sqlalchemy.orm import Session
from . import models, schemas

def create_item(db: Session, item: schemas.ItemCreate):
    db_item = models.Item(**item.dict())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item
        

Test via Swagger UI after running the app connected to Postgres.

Module 8 — Alembic Migrations

Outcome: version DB schema and apply migrations.

pip install alembic
alembic init migrations
# configure env.py (set SQLALCHEMY_URL)
alembic revision --autogenerate -m "init"
alembic upgrade head
        
Mini assignment: add a field then autogenerate migration and apply it.

Module 9 — Dockerize FastAPI

Outcome: build Docker image for FastAPI app.

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn","app.main:app","--host","0.0.0.0","--port","8000"]
        

Module 10 — Docker Compose (FastAPI + Postgres)

version: "3.9"
services:
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: fastapi_db
    volumes:
      - pgdata:/var/lib/postgresql/data
  api:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
volumes:
  pgdata:
        

Run: docker-compose up --build

Module 11 — Authentication (JWT Basics)

Outcome: protect endpoints using JWT tokens (login & protected route).

# jwt_utils.py (simplified)
from datetime import datetime, timedelta
from jose import jwt

SECRET_KEY = "change-me"
ALGORITHM = "HS256"

def create_access_token(data: dict, minutes: int = 60):
    to_encode = data.copy()
    to_encode.update({"exp": datetime.utcnow() + timedelta(minutes=minutes)})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
        
Mini assignment: restrict /items/create to authenticated users only.

Module 12 — Deployment (Render / Railway / Docker)

Outcome: prepare app for production, Dockerize, push to GitHub and deploy.

Checklist

  • Secure secrets via environment variables
  • Use Gunicorn/Uvicorn worker for production
  • Use persistent DB (cloud DB or managed Postgres)
Mini assignment: deploy your project to Render (free tier) and share the live URL.

Assessment: MCQs, Short Answers & Coding

MCQs (sample)

  1. FastAPI is built on which spec?
    Answer: OpenAPI
  2. Which command runs FastAPI? uvicorn main:app --reload

Short answer

  1. Explain Alembic and migrations.
  2. Difference between Pydantic schema and SQLAlchemy model.

Coding

  1. Implement /double/{num} that returns double the number.
  2. Create Pydantic model Student(name, age, dept).

Instructor Answer Key (Selected)

Short Answers

Alembic: DB migrations tool that versions schema changes. Use alembic revision --autogenerate.

MCQ Answers

  • FastAPI spec: OpenAPI

Sample Code Solutions

@app.get("/double/{num}")
def double(num: int):
    return {"double": num * 2}
        

Internship-Style Final Project — Library Management API

Requirements: Books CRUD, Users, Borrow records, JWT auth, Dockerized, Deployed. Deliverables: GitHub repo, PDF report, demo video.

Endpoints (minimum)

  • Books: POST/GET/GET/{id}/PUT/DELETE
  • Users: register/login/profile
  • Borrow: POST borrow/GET user borrows

Grading Rubric

ItemMarks
Functionality (CRUD)40
Auth & Security20
Docker + Deployment20
Documentation & Demo20

Export / Print

To create a printable PDF: copy this page's content into Google Docs (paste as plain text), adjust formatting, then File → Download → PDF.

No comments:

Post a Comment

FAST API - Intro

 https://fastapi-hha68n1.gamma.site/