A server-rendered todo application built with FastAPI, SQLAlchemy, and Jinja2 — featuring JWT authentication, per-user task lists, and an admin panel.
- User registration and login with JWT (OAuth2 password flow)
- Passwords hashed with bcrypt (passlib)
- Per-user todo CRUD — title, description, priority, complete status
- Admin routes for managing users and tasks
- Server-rendered UI with Jinja2 templates and Bootstrap
- Alembic migrations (e.g. adding a phone number to users)
- pytest test scaffolding
| Area | Technologies |
|---|---|
| Framework | FastAPI |
| Database | SQLite + SQLAlchemy, Alembic migrations |
| Auth | python-jose (JWT), passlib + bcrypt |
| Frontend | Jinja2 templates, Bootstrap, vanilla JS |
| Testing | pytest |
git clone https://github.com/shin0biX/FastAPI-Todo.git
cd FastAPI-Todo
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
alembic upgrade head # apply migrations
uvicorn main:app --reload
Open http://127.0.0.1:8000 — you'll be redirected to the todo page; register and log in from there.
Optionally set a custom JWT secret in the environment:
export SECRET_KEY="a-long-random-string"
FastAPI-Todo/
├── main.py # App entry point, mounts routers and static files
├── models.py # Todos and Users models
├── database.py # Engine + session setup
├── routers/
│ ├── auth.py # Register / login / JWT
│ ├── todos.py # Todo pages and endpoints
│ ├── admin.py # Admin-only operations
│ └── users.py # User info endpoints
├── alembic/ # Database migrations
├── templates/ # Jinja2 templates
├── static/ # CSS / JS assets
├── test/ # pytest scaffolding
└── requirements.txt
| Area | Endpoint | Description |
|---|---|---|
| Auth | GET /auth/login-page |
Login page |
| Auth | GET /auth/register-page |
Registration page |
| Auth | POST /auth/token |
Obtain a JWT access token |
| Todos | GET /todos/todo-page |
Todo list page |
| Admin | /admin/... |
Admin-only management endpoints |
Interactive docs are available at /docs when running locally.
- This is a learning project — the default JWT secret is a placeholder and should be replaced in production.
- The local SQLite database is created automatically on first run and is gitignored.