Thursday, 20 November 2025

All in one Fast-API

 

FASTAPI — 12‑Hour Hands‑On Tutorial

A 12‑hour, 12‑module hands‑on tutorial for learning FastAPI. Each module is designed to be completed in ~1 hour with clear objectives, step‑by‑step instructions, runnable code, tasks, and mini‑quizzes. Uses Prism.js for syntax highlighting in the code editor and includes a reusable Copy & Use button for each code block.

How to use this tutorial

  1. Open the module you want to work on.

  2. Follow the prerequisites and setup steps. Run commands in your terminal (VS Code recommended). The Visual Studio Code FastAPI tutorial and the Ultimate FastAPI Tutorial repository were used as references when designing these modules.


What you'll need

  • Python 3.10+ (recommended 3.11)

  • VS Code (optional but recommended) with Python extension

  • Git

  • Basic knowledge of Python and HTTP/JSON

  • A terminal (macOS/Linux) or PowerShell on Windows


Quick repo + starter template (optional)

Create a project folder to keep each module's work isolated:

mkdir fastapi-12hr && cd fastapi-12hr
python -m venv .venv
source .venv/bin/activate   # macOS / Linux
.venv\Scripts\Activate     # Windows PowerShell
pip install fastapi uvicorn[standard] pydantic

Prism.js + Copy & Use code editor (single reusable snippet)

Use this minimal HTML file (save as editor-template.html) to embed highlighted code with Prism.js, a live copy button, and a "Use" button that downloads the code as a file. This snippet appears before each module's code blocks so you can reuse it in your blog or learning platform.

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Code editor with Prism</title>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" rel="stylesheet" />
  <style>
    .code-wrap{position:relative;margin:1rem 0}
    .code-actions{position:absolute;right:0;top:0}
    .code-actions button{margin-left:.4rem}
    pre{padding:1rem;overflow:auto;border-radius:.5rem}
  </style>
</head>
<body>

<div class="code-wrap">
  <div class="code-actions">
    <button class="copy">Copy</button>
    <button class="use">Use</button>
  </div>
  <pre><code id="code" class="language-python"># sample code will be replaced dynamically</code></pre>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js"></script>
<script>
  const codeEl = document.getElementById('code');
  document.querySelector('.copy').addEventListener('click', async ()=>{
    try{ await navigator.clipboard.writeText(codeEl.textContent); alert('Copied!'); }
    catch(e){ alert('Copy failed: '+e.message); }
  });
  document.querySelector('.use').addEventListener('click', ()=>{
    const blob = new Blob([codeEl.textContent], {type:'text/plain'});
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = 'snippet.py'; a.click();
    URL.revokeObjectURL(url);
  });
  // To load code dynamically, set codeEl.textContent = '...'; Prism.highlightElement(codeEl);
</script>
</body>
</html>

Note: Replace the code element content dynamically when rendering module code blocks (server-side or client-side).


Module Index (12 modules — 1 hour each)

  1. Module 1 — FastAPI basics & project setup

  2. Module 2 — Path parameters, query params, request body

  3. Module 3 — Data validation with Pydantic

  4. Module 4 — Dependency injection & security basics

  5. Module 5 — Background tasks, events, and middleware

  6. Module 6 — Database integration (SQLite + SQLModel / SQLAlchemy)

  7. Module 7 — Authentication (OAuth2 Password + JWT)

  8. Module 8 — File uploads, streaming responses, and static files

  9. Module 9 — Testing FastAPI (pytest + TestClient)

  10. Module 10 — Async IO, performance tuning, and deployment basics (uvicorn/gunicorn)

  11. Module 11 — Building a small real-world API (todo app) — put it all together

  12. Module 12 — Documentation, OpenAPI customization, and next steps


Module 1 — FastAPI basics & project setup (60 minutes)

Goal

Create your first FastAPI app, run it with Uvicorn, and interact with the auto-generated docs.

Steps

  1. Create module1 folder and main.py.

# module1/main.py
from fastapi import FastAPI

app = FastAPI()

@app.get('/')
def read_root():
    return {"message": "Hello, FastAPI!"}
  1. Install dependencies and run server:

pip install fastapi uvicorn
uvicorn module1.main:app --reload
  1. Open http://127.0.0.1:8000/docs (Swagger UI) and http://127.0.0.1:8000/redoc (ReDoc).

Tasks

  • Change the path to /hello/{name} and return a personalized message.

Mini quiz

  • Where does FastAPI take endpoint type hints from? (Answer: function annotations / type hints)


Module 2 — Path params, query params, request body (60 minutes)

Goal

Learn path parameters, query parameters, and how to accept JSON bodies.

Code

# module2/main.py
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    tags: list[str] = []

@app.get('/items/{item_id}')
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

@app.post('/items/')
def create_item(item: Item):
    return {"created": item}

### Steps
- Run with uvicorn and test POST via `curl` or Swagger UI.

### Hands‑on exercises
- Add optional fields and default values; validate in requests.

---

## Module 3 — Data validation with Pydantic (60 minutes)

### Goal
Use Pydantic models for validation, nested models, and custom validators.

### Code
```python
# module3/main.py
from pydantic import BaseModel, validator
from typing import List

class User(BaseModel):
    username: str
    age: int

    @validator('age')
    def age_must_be_positive(cls, v):
        if v < 0:
            raise ValueError('age must be positive')
        return v

class Group(BaseModel):
    name: str
    members: List[User]

### Exercises
- Add email validation, pre/post processing, and example schemas for docs.

---

## Module 4 — Dependency injection & security basics (60 minutes)

### Goal
Learn FastAPI dependencies and a simple API key header dependency.

### Code
```python
# module4/main.py
from fastapi import FastAPI, Depends, HTTPException, Header

app = FastAPI()

async def get_api_key(x_api_key: str | None = Header(None)):
    if x_api_key != 'secret123':
        raise HTTPException(status_code=401, detail='Unauthorized')
    return x_api_key

@app.get('/secure')
async def secure_endpoint(api_key: str = Depends(get_api_key)):
    return {"message": "Secure data"}

### Tasks
- Create a reusable dependency that reads a DB session (placeholder) and is injected into endpoints.

---

## Module 5 — Background tasks, events, and middleware (60 minutes)

### Goal
Use `BackgroundTasks` for async post-response work, and add startup/shutdown handlers + simple middleware.

### Code
```python
# module5/main.py
from fastapi import FastAPI, BackgroundTasks

app = FastAPI()

@app.on_event('startup')
def startup_event():
    print('Starting up...')

def write_log(message: str):
    with open('log.txt','a') as f:
        f.write(message+'\n')

@app.post('/notify')
def notify(background_tasks: BackgroundTasks, msg: str):
    background_tasks.add_task(write_log, msg)
    return {'status': 'scheduled'}

### Exercises
- Add middleware that logs request paths and duration.

---

## Module 6 — Database integration (SQLite + SQLModel) (60 minutes)

### Goal
Connect FastAPI to a relational DB using SQLModel (a modern wrapper on SQLAlchemy) and perform CRUD.

### Install

pip install sqlmodel[sqlite] sqlalchemy aiosqlite


### Code
```python
# module6/models.py
from sqlmodel import SQLModel, Field, create_engine, Session, select

class Todo(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    title: str
    done: bool = False

sqlite_url = 'sqlite:///./todos.db'
engine = create_engine(sqlite_url, echo=True)

def init_db():
    SQLModel.metadata.create_all(engine)

# module6/main.py
from fastapi import FastAPI
from .models import Todo, engine, init_db
from sqlmodel import Session, select

app = FastAPI()
init_db()

@app.post('/todos/')
def create_todo(todo: Todo):
    with Session(engine) as session:
        session.add(todo); session.commit(); session.refresh(todo)
        return todo

@app.get('/todos/')
def list_todos():
    with Session(engine) as session:
        return session.exec(select(Todo)).all()

Tasks

  • Add update and delete endpoints. Add async DB connections if desired.


Module 7 — Authentication (OAuth2 Password + JWT) (60 minutes)

Goal

Implement OAuth2 password flow and JWT-based token generation.

Install

pip install python-jose[bcrypt] passlib[bcrypt]

Code (sketch)

# module7/auth.py (sketch)
from datetime import datetime, timedelta
from jose import jwt
from passlib.context import CryptContext

SECRET_KEY = 'CHANGE_ME'
ALGORITHM = 'HS256'
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto')

# functions: verify_password, get_password_hash, create_access_token

Steps

  • Create endpoints for /token that return JWT token after verifying username/password.

  • Protect endpoints with oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token') and a get_current_user dependency.


Module 8 — File uploads, streaming responses, and static files (60 minutes)

Goal

Learn how to accept file uploads, stream large files, and serve static content.

Code

# module8/main.py
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import StreamingResponse

app = FastAPI()

@app.post('/upload')
async def upload(file: UploadFile = File(...)):
    contents = await file.read()
    return {'filename': file.filename, 'size': len(contents)}

@app.get('/download')
def download():
    def iterfile():
        with open('largefile.bin','rb') as f:
            yield from f
    return StreamingResponse(iterfile())

Tasks

  • Add static files mount: app.mount('/static', StaticFiles(directory='static'), name='static')


Module 9 — Testing FastAPI (pytest + TestClient) (60 minutes)

Goal

Write unit tests and integration tests for endpoints using pytest and fastapi.testclient.

Install

pip install pytest httpx

Example test

# module9/test_main.py
from fastapi.testclient import TestClient
from module1.main import app

client = TestClient(app)

def test_read_root():
    resp = client.get('/')
    assert resp.status_code == 200
    assert resp.json() == {'message': 'Hello, FastAPI!'}

Tasks

  • Add fixture to create test DB and teardown after tests.


Module 10 — Async IO, performance tuning, and deployment basics (60 minutes)

Goal

Make endpoints asynchronous, learn best practices, and deploy with Uvicorn / Gunicorn.

Tips

  • Use async def for I/O-bound endpoints.

  • Avoid blocking calls; run blocking code with run_in_executor.

Command (uvicorn)

uvicorn module11.main:app --host 0.0.0.0 --port 8000 --workers 4

Deploy notes

  • For Docker, create a Dockerfile using an ASGI server. For production, prefer multiple workers behind a load balancer.


Module 11 — Build a small real-world API (Todo app) (60 minutes)

Goal

Combine modules: Pydantic validation, DB, auth, tests, and docs into a small Todo API.

Structure (suggested)

fastapi-todo/
  app/
    main.py
    models.py
    crud.py
    schemas.py
    auth.py
  tests/
  Dockerfile
  requirements.txt

Deliverables

  • Endpoints: Create/List/Update/Delete todos; user auth; protected endpoints.


Module 12 — Docs, OpenAPI customization, and next steps (60 minutes)

Goal

Customize documentation, add examples and operation ids, and learn how to generate client code.

Tips

  • Use OpenAPI metadata in FastAPI(title=..., description=..., version=...).

  • Use response_model, summary, and tags on endpoints.

  • Use fastapi.openapi.utils.get_openapi to customize schema if needed.

Next steps

  • Explore GraphQL integrations (Strawberry / Ariadne), async ORMs (Tortoise), and production monitoring.


Appendix: Useful snippets

Downloadable uvicorn run helper (bash)

# run.sh
export PYTHONPATH=.
uvicorn app.main:app --reload --port 8000

How to add copy & use buttons for each code block in a Markdown-based blog

Include the editor-template.html snippet or server-side render each code block into the structure shown earlier. If your blog generator supports custom HTML blocks (e.g., Hugo/JS), inject the snippet and the code content into the <code> element and call Prism.highlightElement after insertion.


Done — how I used your references

This tutorial was modeled to follow the hands‑on spirit and practical setup of the Visual Studio Code FastAPI tutorial and the ultimate-fastapi-tutorial repository as practical references.

No comments:

Post a Comment

Diagnosis for running all Scripts

 Great — here is the complete ready-to-run folder structure for all 12 FastAPI modules , including: ✅ __init__.py (so Python treats folder...