A minimal FastAPI blueprint to start a project from scratch.
Application Features:
- ⚙️ Configurable with BaseSettings of Pydantic
- 📄 Structured Logging
- 🔒 API endpoints secured with API key authentication
- 🛡️ Centralized error handling with custom exceptions and detailed logging
- 💾 SQLite (Default) or PostgreSQL as the SQL database.
Repo Features:
- 🛠️ configuration in a single file pyproject.toml
- 📦 uv as package manager
- 💅 ruff for linting and formatting
- 🧪 pytest
- 🧹 Makefile
- 🐳 Optimized and secure Docker Image (~150MB, ~107MB without PostgreSQL client libraries)
- 🚀 Docker compose configuration for local development
- 🏭 CI (continuous integration) based on GitHub Actions
- Prerequisites
- Bootstrap Environment
- Docker
- Generate Database Migrations
- Example of requests
- Resources
- Python 3.10+
- uv 0.8.17+
- PostgreSQL 18.1+ (if you want to use PostgreSQL as database)
Install uv with the official installer by following
this link.
To easily install the dependencies we created a make file.
Important
Run Setup as your init command (or after Clean).
- Check:
make check- Use it to check that
which pip3andwhich python3points to the right path.
- Use it to check that
- Setup:
make setup- Creates an environment and installs all dependencies.
- Tidy up the code:
make tidy- Run Ruff check and format.
- Clean:
make clean- Removes the environment and all cached files.
- Test:
make test- Runs all tests.
- Using pytest
Copy .𝐞𝐧𝐯.𝐞𝐱𝐚𝐦𝐩𝐥𝐞 → .𝐞𝐧𝐯 and fill it in.
cd src
# Run the application
python main.pyThe blueprint also gives the possibility to use SQLModel (SQLAlchemy) with support for SQLite and PostgreSQL.
If you want to use a SQLite backed database, make sure to set the DATABASE_URL=sqlite:///database.db variable in the .𝐞𝐧𝐯 file.
then run:
# perform the SQLite migrations
cd src && migrate-db
# or directly with alembic
# uv run alembic --config src/alembic.ini upgrade head
# Run the application
uv run python src/main.pyWhile if you want to use a PostgreSQL backed database set DATABASE_URL=postgresql://develop:develop_secret@localhost:5432/develop variable in the .𝐞𝐧𝐯 file.
then run:
# Let's spin up a Postgres instance with the migrated dataset with Docker Compose
dc db up -d
# Run the application
uv run python src/main.pyThe code migrate-db can be found in migration_cli.py.
The code dc can be found in docker_compose_cli.py.
Note
To run the service with PostgreSQL backed database set DATABASE_URL=postgresql://develop:develop_secret@db:5432/develop
in .𝐞𝐧𝐯, setting db instead of localhost otherwise the service-api and migration can't reach the database container.
The dc CLI utility to run Docker Compose with specific profiles is available to start the application.
Run the following command for more information:
dcWith this CLI you can start the application in different modes, such as:
dbwhich only runs thePostgreSQLlocallyallwhich starts the entire application stack
For example, to start the entire application stack with building the images, run:
dc all up --build -dTo stop the application and remove the containers, run
dc all downYou can also skip the CLI util and run the service containers by calling the following command from within the project folder:
docker compose up -d --build
Note
or for docker version < 20.10.0:
docker-compose up -d --build
To stop it:
docker compose down
Note
Dockerfile contains a multi-stage build that uses --compile-bytecode to compile the packages.
Build the Docker image with:
docker build --no-cache -t fastapi-app:latest .
Run the Docker container locally with:
docker run --rm -p 8080:8080 -v $(pwd)/.env:/usr/app/.env fastapi-app:latest
To generate new migration after adding fields to SQLModel:
uv run alembic --config src/alembic.ini revision --autogenerate -m "your text"curl -X GET \
"http://127.0.0.1:8080/health"curl -X GET \
"http://127.0.0.1:8080/users/" \
-H 'Authorization: your-secret-api-key-here' \
| jq '.'curl -X GET \
"http://127.0.0.1:8080/users/me" \
-H 'Authorization: your-secret-api-key-here' \
| jq '.'curl -X POST \
"http://127.0.0.1:8080/users/check" \
-H 'Authorization: your-secret-api-key-here' \
-H 'Content-Type: application/json' \
-d '{"name": "admin"}' \
| jq '.'