A production-ready REST API for managing romance books and novelists, built with FastAPI, PostgreSQL, async SQLAlchemy, JWT authentication, automated testing, Docker, and CI/CD.
π Live API: https://madr-api.fly.dev
π Interactive API Docs: https://madr-api.fly.dev/docs
MADR is a backend application for managing romance books, novelists, and user accounts.
The project was developed as a backend capstone and independently implemented from a set of functional requirements, with additional focus on production-oriented practices such as authentication, database migrations, containerization, automated tests, and continuous deployment.
the API includes authentication, filtering, pagination, data validation, relational integrity, password hashing, database constraints, and automated deployment.
- User registration
- OAuth2 password flow
- JWT access tokens
- Token refresh
- Password hashing with Argon2
- Protected endpoints
- Current-user account management
- Create an account
- Retrieve authenticated user
- Update username, email, or password
- Delete account
- Duplicate username and email protection
- Username normalization
- Create books
- List books
- Retrieve a book by ID
- Update books
- Delete books
- Filter by title
- Filter by publication year
- Pagination
- Unique book titles
- Relationship with novelists
- Create novelists
- List novelists
- Retrieve a novelist by ID
- Update novelists
- Delete novelists
- Partial name filtering
- Pagination
- Unique novelist names
- Protection against deleting novelists that still have registered books
- Python 3.14
- FastAPI
- Pydantic
- SQLAlchemy 2
- Psycopg
- PostgreSQL
- OAuth2
- JWT
- PyJWT
- pwdlib
- Argon2
- PostgreSQL
- Alembic
- Supabase
- Pytest
- pytest-asyncio
- pytest-cov
- Testcontainers
- Ruff
- Poe the Poet
- Docker
- Docker Compose
- Fly.io
- GitHub Actions
- Poetry
The application uses an asynchronous SQLAlchemy session to communicate with PostgreSQL.
Database schema changes are managed through Alembic migrations.
The main API groups are:
/auth
/users
/books
/novelists
Examples:
POST /users/
POST /auth/token
POST /auth/refresh-token
GET /users/me
PATCH /users/me
DELETE /users/me
POST /books/
GET /books/
GET /books/{book_id}
PATCH /books/{book_id}
DELETE /books/{book_id}
POST /novelists/
GET /novelists/
GET /novelists/{novelist_id}
PATCH /novelists/{novelist_id}
DELETE /novelists/{novelist_id}For the complete request and response schemas, use the interactive documentation:
Protected routes use Bearer authentication.
User credentials
β
βΌ
POST /auth/token
β
βΌ
JWT access token
β
βΌ
Authorization: Bearer <token>
β
βΌ
Protected endpoint
The JWT subject identifies the authenticated user through their email.
Passwords are never stored directly. They are hashed before being persisted in the database.
The application currently contains three main entities:
User
Novelist
β
β 1:N
βΌ
Book
A novelist can have multiple books, while every book belongs to one novelist.
Database-level uniqueness constraints protect:
- user emails
- usernames
- book titles
- novelist names
Application-level validation provides readable HTTP conflict responses before attempting invalid operations.
You will need:
- Python 3.14+
- Poetry
- PostgreSQL
Clone the repository:
git clone https://github.com/iamsaturn/madr-api.git
cd madr-apiInstall the dependencies:
poetry installCreate a .env file:
DATABASE_URL=postgresql+psycopg://USER:PASSWORD@HOST:PORT/DATABASE
SECRET_KEY=your-secret-key
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRES=60Apply database migrations:
poetry run alembic upgrade headStart the development server:
poetry run poe runThe API will be available at:
http://localhost:8000
Interactive documentation:
http://localhost:8000/docs
The project can also run as a containerized environment.
Build and start the application and PostgreSQL:
docker compose up --buildDocker Compose creates:
api
β
βββ FastAPI container
db
β
βββ PostgreSQL container
The API container communicates with PostgreSQL through Docker's internal network.
To stop the containers:
docker compose downTests run against a real temporary PostgreSQL instance using Testcontainers rather than replacing the database layer with mocks.
Run the test suite with:
poetry run poe testThe test command also generates a coverage report.
Run linting with:
poetry run poe lintThis allows the application stack to be tested against:
FastAPI
β
SQLAlchemy
β
PostgreSQL
rather than testing only isolated functions.
The repository uses GitHub Actions for continuous integration and continuous deployment.
Every push to main triggers the following pipeline:
Push to main
β
βΌ
Checkout repository
β
βΌ
Set up Python
β
βΌ
Install Poetry
β
βΌ
Install dependencies
β
βΌ
Ruff lint
β
βΌ
Pytest + Testcontainers
β
βΌ
Tests passed?
β β
β no β yes
βΌ βΌ
Stop Deploy
β
βΌ
Fly.io
A deployment is only executed when the validation job succeeds.
Production secrets are stored outside the repository and injected through the deployment environment.
The production architecture uses:
GitHub
β
β push
βΌ
GitHub Actions
β
β CI/CD
βΌ
Fly.io
β
β PostgreSQL connection
βΌ
Supabase
The FastAPI application runs inside a Docker container on Fly.io while the production PostgreSQL database is hosted on Supabase.
madr-api/
β
βββ .github/
β βββ workflows/
β βββ deploy.yml
β
βββ madr_api/
β βββ routers/
β β βββ auth.py
β β βββ books.py
β β βββ novelists.py
β β βββ users.py
β β
β βββ app.py
β βββ database.py
β βββ models.py
β βββ schemas.py
β βββ security.py
β βββ settings.py
β
βββ migrations/
β
βββ tests/
β
βββ Dockerfile
βββ compose.yaml
βββ entrypoint.sh
βββ fly.toml
βββ alembic.ini
βββ pyproject.toml
βββ poetry.lock
βββ README.md
This project was built to consolidate backend engineering concepts into a complete deployed application.
Some of the main concepts practiced include:
- REST API design
- HTTP status codes
- dependency injection with FastAPI
- request and response validation
- asynchronous database access
- ORM relationships
- database constraints
- schema migrations
- authentication and authorization
- password hashing
- JWT validation
- integration testing
- containerization
- environment configuration
- cloud deployment
- CI/CD pipelines
iamsaturn
GitHub: https://github.com/iamsaturn