A learning project covering FastAPI fundamentals: request validation, SQLAlchemy, JWT-based authentication with httponly cookies, role-based access control (RBAC), custom exception handling, static type checking with mypy, and a pytest test suite with coverage reporting.
- Python 3.13+
- uv
Install dependencies:
uv syncStart the development server:
uv run uvicorn main:app --reloadThe API will be available at:
http://127.0.0.1:8000
Swagger documentation:
http://127.0.0.1:8000/docs
ReDoc:
http://127.0.0.1:8000/redoc
- JWT-based login, issued as an httponly, samesite cookie (
access_token) - Custom exception hierarchy (
AppExceptionand subclasses) mapped to consistent JSON error responses via FastAPI exception handlers - Auth and role checks implemented as FastAPI dependencies (not middleware) — see
app/dependencies.py - Role-based access control:
/user/*routes require theadminrole, enforced via aauthorized(roles)dependency factory - In-memory, per-key rate limiting on
/auth/login(seeapp/utils/rate_limiter.py) — 5 requests per 60 seconds by IP+route - Response schemas built with Pydantic (
from_attributes = True) to keep sensitive fields (e.g. password hashes) out of API responses
Tests use an isolated in-memory SQLite database (via dependency_overrides), never the real dev database.
Run all tests:
uv run pytestRun tests with verbose output:
uv run pytest -vRun a single test file with verbose output:
uv run pytest tests/filename.py -vCoverage runs automatically (see pyproject.toml's addopts). To run it explicitly:
uv run pytest --cov=app --cov-report=term-missing tests/Run the type checker with mypy:
uv run mypy .If mypy is not installed:
uv add --dev mypy├─ .python-version
├─ app
│ ├─ database.py
│ ├─ dependencies.py
│ ├─ exceptions.py
│ ├─ models
│ │ ├─ user.py
│ │ └─ __init__.py
│ ├─ routes
│ │ ├─ auth.py
│ │ ├─ user.py
│ │ └─ __init__.py
│ ├─ schema
│ │ ├─ api_response.py
│ │ ├─ auth.py
│ │ ├─ user.py
│ │ └─ __init__.py
│ ├─ services
│ │ ├─ auth_service.py
│ │ ├─ user_service.py
│ │ └─ __init__.py
│ ├─ utils
│ │ ├─ jwt.py
│ │ ├─ password.py
│ │ ├─ rate_limiter.py
│ │ ├─ response.py
│ │ └─ __init__.py
│ └─ __init__.py
├─ main.py
├─ pyproject.toml
├─ README.md
├─ test.db
├─ tests
│ ├─ conftest.py
│ ├─ test_auth.py
│ ├─ test_exceptions.py
│ ├─ test_password.py
│ └─ test_user.py
└─ uv.lock
uv syncuv add <package>uv add --dev <package>