Docs
task api
๐ Task Management API
A complete REST API project demonstrating FastAPI, SQLAlchemy, JWT authentication, and Docker deployment.
๐ฏ Learning Objectives
After working through this project, you'll understand:
- โขFastAPI Framework - Building modern Python APIs with automatic documentation
- โขSQLAlchemy ORM - Database modeling with Python objects
- โขJWT Authentication - Secure token-based authentication
- โขPydantic Validation - Request/response data validation with type hints
- โขDependency Injection - FastAPI's DI system for clean, testable code
- โขDocker Deployment - Containerizing and deploying Python applications
Features
- โขUser registration and login with JWT tokens
- โขFull CRUD operations for tasks
- โขTask categories, priorities, and due dates
- โขFiltering and pagination
- โขTask completion statistics
- โขPostgreSQL database (SQLite for development)
- โขDocker Compose for production
- โขComprehensive test suite
๐ Quick Start
Option 1: Local Development (Recommended for Learning)
cd 01_task_api
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Run the API
uvicorn app.main:app --reload
Option 2: Docker Compose (Production-like)
cd 01_task_api
docker-compose up -d
Access the API
- โขAPI Root: http://localhost:8000
- โขInteractive Docs (Swagger): http://localhost:8000/docs
- โขAlternative Docs (ReDoc): http://localhost:8000/redoc
- โขHealth Check: http://localhost:8000/health
๐ API Endpoints
Authentication
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/users/register | Register a new user |
| POST | /api/users/login | Login and get JWT token |
| GET | /api/users/me | Get current user profile |
| DELETE | /api/users/me | Delete current user account |
Tasks (Authenticated)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/tasks/ | Create a new task |
| GET | /api/tasks/ | List all tasks (with filters) |
| GET | /api/tasks/{id} | Get specific task |
| PUT | /api/tasks/{id} | Update task |
| DELETE | /api/tasks/{id} | Delete task |
| PATCH | /api/tasks/{id}/complete | Mark task complete |
| GET | /api/tasks/stats/summary | Get task statistics |
Query Parameters for GET /api/tasks/
- โข
skip- Pagination offset (default: 0) - โข
limit- Items per page (default: 100, max: 100) - โข
completed- Filter by status (true/false) - โข
priority- Filter by priority (low/medium/high/urgent) - โข
category- Filter by category name
๐ก Usage Examples
Register a User
curl -X POST http://localhost:8000/api/users/register \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "username": "myuser", "password": "mypassword123"}'
Login and Get Token
curl -X POST http://localhost:8000/api/users/login \
-d "username=myuser&password=mypassword123"
# Response: {"access_token": "eyJ...", "token_type": "bearer"}
Create a Task
curl -X POST http://localhost:8000/api/tasks/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Learn FastAPI",
"description": "Complete the tutorial",
"priority": "high",
"category": "learning"
}'
List Tasks with Filters
# Get high priority incomplete tasks
curl -X GET "http://localhost:8000/api/tasks/?completed=false&priority=high" \
-H "Authorization: Bearer YOUR_TOKEN"
๐ Project Structure
01_task_api/
โโโ app/
โ โโโ __init__.py # Package marker
โ โโโ main.py # FastAPI application entry point
โ โโโ config.py # Settings with pydantic-settings
โ โโโ database.py # SQLAlchemy engine and session
โ โโโ models.py # ORM models (User, Task)
โ โโโ schemas.py # Pydantic request/response models
โ โโโ auth.py # JWT authentication utilities
โ โโโ routers/
โ โโโ __init__.py
โ โโโ users.py # User registration, login, profile
โ โโโ tasks.py # Task CRUD operations
โโโ tests/
โ โโโ __init__.py
โ โโโ conftest.py # Test fixtures
โ โโโ test_api.py # API tests
โโโ Dockerfile # Container definition
โโโ docker-compose.yml # Multi-container setup
โโโ requirements.txt # Python dependencies
โโโ README.md
๐ Key Concepts Explained
FastAPI Application Setup
from fastapi import FastAPI
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Startup and shutdown events."""
# Startup: Create database tables
Base.metadata.create_all(bind=engine)
yield
# Shutdown: Cleanup if needed
app = FastAPI(
title="Task Management API",
lifespan=lifespan
)
Dependency Injection
from fastapi import Depends
from sqlalchemy.orm import Session
def get_db():
"""Database session dependency."""
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/tasks/")
def get_tasks(
db: Session = Depends(get_db), # Database session
user: User = Depends(get_current_user), # Authenticated user
skip: int = 0, # Query parameter
limit: int = 100
):
return db.query(Task).filter(Task.owner_id == user.id).all()
JWT Authentication Flow
# 1. User logs in with username/password
# 2. Server validates credentials
# 3. Server creates JWT token with user info
# 4. Client stores token and sends with each request
# 5. Server validates token and extracts user
def create_access_token(data: dict) -> str:
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=30)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")
Pydantic Schema Validation
from pydantic import BaseModel, Field, EmailStr
class TaskCreate(BaseModel):
title: str = Field(..., min_length=1, max_length=200)
description: str | None = Field(None, max_length=1000)
priority: TaskPriority = TaskPriority.MEDIUM
# Automatic validation on request:
# - title is required (...)
# - title length between 1-200 chars
# - description is optional, max 1000 chars
# - priority defaults to MEDIUM
๐งช Running Tests
# Install test dependencies
pip install pytest pytest-asyncio httpx
# Run all tests
pytest tests/ -v
# Run with coverage
pip install pytest-cov
pytest tests/ --cov=app --cov-report=html
๐ง Configuration
Environment variables (use .env file):
# Database (SQLite by default, PostgreSQL for production)
DATABASE_URL=sqlite:///./tasks.db
# DATABASE_URL=postgresql://user:pass@localhost:5432/tasks
# JWT Settings
SECRET_KEY=your-super-secret-key-change-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
# App Settings
DEBUG=true
๐ Extending the API
Add a New Model
- โขCreate model in
models.py:
class Category(Base):
__tablename__ = "categories"
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
- โขAdd schemas in
schemas.py - โขCreate router in
routers/categories.py - โขRegister router in
main.py
Add Pagination Response
from math import ceil
class PaginatedTasks(BaseModel):
items: list[TaskResponse]
total: int
page: int
per_page: int
pages: int
@router.get("/", response_model=PaginatedTasks)
def list_tasks(page: int = 1, per_page: int = 20):
total = db.query(Task).count()
items = db.query(Task).offset((page-1)*per_page).limit(per_page).all()
return {
"items": items,
"total": total,
"page": page,
"per_page": per_page,
"pages": ceil(total / per_page)
}
๐ Related Learning
- โขFastAPI Official Tutorial
- โขSQLAlchemy ORM Tutorial
- โขJWT.io - Learn about JSON Web Tokens
- โขPydantic Documentation
โ Project Checklist
- โข Run the API and explore
/docs - โข Register a user and login
- โข Create, update, and delete tasks
- โข Try filtering tasks by priority and status
- โข Run the test suite
- โข Add a new field to tasks (e.g., tags)
- โข Deploy with Docker Compose
- โข Add rate limiting middleware