Day 18 of #60DaysOfPython — Took the Day 17 FastAPI + SQLAlchemy project and refactored it for production readiness: fixed bugs, cleaned up code quality, and proved every endpoint works correctly with a full pytest test suite covering all user roles and edge cases.
- Renamed
Exceptions.py→exceptions.py(PEP 8: lowercase module names) - Fixed all imports pointing to the old filename
- Replaced vague error messages like
"do not have Permission "with clear, professional ones - Removed dead code and redundant variable assignments
- Fixed deprecated APIs:
declarative_base,utcnow, Pydantic class-basedConfig - Added correct
status_code=201to POST endpoints that create resources
tests/conftest.py— shared test DB, fixtures, and helper functionstests/test_auth.py— register and login flowstests/test_users.py— /me, /dashboard, role protection, delete accounttests/test_courses.py— create course, list courses, auth protection
17 passed in 20.48s
| Endpoint | Method | Test Coverage |
|---|---|---|
| /register | POST | Success 201, duplicate email 400 |
| /login | POST | Valid credentials 200, wrong password 401 |
| /me | GET | Valid token 200, no token 401 |
| /dashboard | GET | Teacher 200, student 403 |
| /users/{id} | GET | Own profile 200, other user 403 |
| /users/{id} | DELETE | Own account 200, other account 403 |
| /courses | POST | Teacher 201, student 403, no token 401 |
| /courses | GET | Logged in 200, no token 401 |
- FastAPI — API framework
- SQLAlchemy — ORM with SQLite
- Pydantic v2 — request/response validation
- python-jose — JWT token generation and verification
- passlib + bcrypt — password hashing
- pytest + httpx2 — test runner and HTTP client
day18-fastapi-testing/
├── main.py # all route definitions
├── auth.py # JWT logic and role dependencies
├── models.py # SQLAlchemy User and Course models
├── schemas.py # Pydantic request/response schemas
├── database.py # DB engine and session setup
├── exceptions.py # custom HTTP exceptions
├── pagination.py # reusable pagination dependency
├── requirements.txt
└── tests/
├── conftest.py # shared fixtures and test DB
├── test_auth.py
├── test_users.py
└── test_courses.py
pip install -r requirements.txt
uvicorn main:app --reloadpytest -v#60DaysOfPython — rebuilding to professional software development, one project a day.