A powerful, scalable template to kickstart your backend projects. Includes FastAPI with Docker integration, JWT authentication, optional Logfire instrumentation, and PEP-582-based dependency management via Astral's uv
.
Inspired by Radoslav Georgiev's Django Structure for Scale lecture and my own experience, this template offers a structured approach to building scalable web applications.
- β¨ Features
- π Project Structure
- π‘ Getting Started
- π οΈ Using auto-module.py
- π JWT Auth & Security
- π License
- π Deploy
- π€ Contribute to the Project
- π¬ Contact
- FastAPI template with JWT authentication and Alembic migrations.
- Docker & docker-compose configs for zero-friction container development.
- Astral
uv
for dependency installation and script execution (no manualvenv
activation). - Logfire auto-instrumentation: set
LOGFIRE_TOKEN
in your environment and the app will automatically send logs to Pydantic Logfire. - Modular structure inspired by scaling best practices.
- Optional
uvloop
integration for improved asyncio performance (Linux/macOS only).
.vscode/
alembic/
app/
author/
routes/
__init__.py
base.py
schemas/
__init__.py
base.py
create.py
edit.py
response.py
annotations.py
apis.py
crud.py
exceptions.py
formatters.py
models.py
selectors.py
services.py
common/
annotations.py
auth.py
crud.py
dependencies.py
exceptions.py
paginators.py
schemas.py
security.py
types.py
utils.py
core/
database.py
handlers.py
settings.py
tags.py
external/
main.py
tests/
.env_sample
.flake8
.gitignore
.pylintrc
.python-version
alembic.ini
auto-module.py
docker-compose.yml
Dockerfile
LICENSE
pyproject.toml
pytest.ini
railway.toml
README.md
requirements.txt
start.sh
uv.lock
- Docker & Docker Compose (optional)
uv
installed globally
git clone https://github.com/GrandGaleTechnologies/behemoth-fastapi
cd behemoth-fastapi
# Optional: add uvloop (doesnt work well on windows)
uv add uvloop
uv venv
Copy .env_sample
to .env
and set values. If provided, LOGFIRE_TOKEN
will enable Pydantic Logfire logging. check this on how to get your logfire token
# With uv
uv run alembic upgrade head
uv run fastapi dev
uv run fastapi run
This script automates creation of new FastAPI modules with a consistent folder layout:
app/
βββ ModuleName/
βββ routes/__init__.py
βββ routes/base.py
βββ schemas/base.py
βββ schemas/create.py
βββ schemas/edit.py
βββ schemas/response.py
βββ apis.py
βββ models.py
βββ services.py
βββ selectors.py
βββ exceptions.py
βββ formatters.py
uv run auto-module.py
Follow the prompts to specify the module name.
- Implemented in
common/auth.py
andcommon/security.py
- Leverages FastAPI's
Depends
and reusableget_current_user()
function - Tokens include expiration and are signed using a secret key in
.env
To protect a route:
from common.dependencies import get_current_user
@app.get("/secure-data")
def secure_data(user: User = Depends(get_current_user)):
return {"message": f"Hello, {user.username}!"}
- User logs in via
/login
endpoint β receives JWT access token - Frontend stores token (e.g., in localStorage or Authorization header)
- Token is sent with each protected request
- Backend validates token and grants access
This project uses Redis-based rate limiting through fastapi-limiter
. By default, it allows 3 requests per second per endpoint.
You can run Redis directly as a standalone container:
docker run -d \
--name behemoth-redis \
-p 6379:6379 \
-v redis_data:/data \
redis:latest
This will:
- Run Redis in detached mode (
-d
) - Name the container
behemoth-redis
- Expose Redis on port
6379
- Persist data in a Docker-managed volume (
redis_data
)
docker exec -it behemoth-redis redis-cli ping
You should see PONG
as the response.
Update your .env
file with the Redis container URL (since itβs exposed on localhost):
REDIS_BROKER_URL=redis://localhost:6379/0
-
Swagger UI
- Navigate to
http://localhost:8000
- Make multiple rapid requests to any endpoint
- After 3 requests within 1 second, youβll receive a 429 Too Many Requests
- Navigate to
-
Curl
for i in {1..4}; do curl http://localhost:8000/health; done
docker exec -it behemoth-redis redis-cli monitor
If Redis connection fails:
- Check container status:
docker ps -f name=behemoth-redis
- View logs:
docker logs behemoth-redis
- Restart Redis:
docker restart behemoth-redis
Update your .env
file with the Redis container URL:
REDIS_BROKER_URL=redis://redis:6379/0
Rate limiting is configured in app/main.py
:
REQ_RATE = 3 # Number of requests allowed
REQ_RATE_TIME = 1 # Time window in seconds
This means each endpoint allows 3 requests per second. After exceeding this limit, requests will receive a 429 (Too Many Requests) response.
-
Swagger UI:
- Navigate to
http://localhost:8000
- Make multiple rapid requests to any endpoint
- After 3 requests within 1 second, you'll receive a 429 response
- Navigate to
-
Using Docker CLI:
# Make multiple requests quickly
for ($i = 1; $i -le 4; $i++) {
docker-compose exec api curl http://localhost:8000/health
}
Monitor Redis rate limiting in real-time:
docker-compose exec redis redis-cli monitor
If Redis connection fails:
- Check Redis container status:
docker-compose ps redis
- View Redis logs:
docker-compose logs redis
- Verify Redis network connectivity:
docker-compose exec api ping redis
- Check Redis container health:
docker inspect -f '{{.State.Health.Status}}' behemoth-fastapi-redis-1
- Restart Redis
This project is licensed under the MIT License - see the LICENSE file for details.
Deploy this template on Railway:
Contributions are welcome! Fork the repo, create a branch, and submit a PR. Engage in discussions for ideas and improvements.
- Name: GrandGale Technologies
- Email: [email protected]
- GitHub: https://github.com/GrandGaleTechnologies
- LinkedIn: https://linkedin.com/in/angobello0
- Upwork: https://www.upwork.com/freelancers/~01bb1007bf8311388a
- Instagram: https://www.instagram.com/bello_ango0/