Development Environment¶
This guide covers the tools and configuration for an optimal development experience.
Code quality tools¶
The project uses Ruff for formatting and linting, and mypy for strict type checking.
Ruff and mypy are configured in pyproject.toml and ruff.toml; Git hooks are
configured in prek.toml.
Formatting with Ruff¶
Ruff handles code formatting and linting. It is installed in the project dev
environment for editor integration, and prek runs it through local hooks.
Type checking¶
The project is configured for strict type checking with mypy. It runs through
prek as part of the lint workflow:
| Tool | Command | Configuration |
|---|---|---|
| mypy | uv run prek run mypy --all-files |
pyproject.toml, prek.toml |
The mypy configuration enables the Django stubs plugin and the diwire plugin, so framework settings and injected callables are checked with the same rules CI uses.
Git hooks¶
The project uses prek for local hooks. By default, prek run checks staged
files; make lint runs the same hooks across the whole repository.
# prek.toml
# Install hooks
uv run prek install
# Check staged files
uv run prek run
# Check the whole repository
uv run prek run --all-files
Hooks include:
- Ruff formatting and linting
- mypy strict type checking
- Trailing whitespace removal
- YAML/TOML validation
- uv lockfile validation
- Large file detection
IDE configuration¶
VS Code¶
Recommended extensions:
- Python (Microsoft)
- Ruff (Astral Software)
- Mypy Type Checker (Microsoft)
Create .vscode/settings.json:
{
"python.defaultInterpreterPath": ".venv/bin/python",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
}
},
"python.analysis.typeCheckingMode": "strict",
"mypy-type-checker.args": [],
"ruff.configurationPreference": "filesystemFirst"
}
PyCharm¶
- Set interpreter: Point to
.venv/bin/python - Enable Ruff: Settings → Plugins → Install "Ruff"
- Configure mypy: Settings → Tools → External Tools → Add mypy
- Mark source root: Right-click
src/→ Mark Directory as → Sources Root
Environment variables¶
Local development¶
The setup wizard writes .env for the database, Redis, storage, and public
origin choices you made:
The .env.example file stays committed as a reference. Key variables for
development:
# .env.example
# Django
DJANGO_SECRET_KEY=development-secret-key-change-in-production
DJANGO_DEBUG=true
# Database
DATABASE_URL=postgres://postgres:example-postgres-password@localhost:5432/postgres
# or DATABASE_URL=sqlite:///db.sqlite3
# Redis
REDIS_URL=redis://localhost:6379/0
# Logging
LOGGING_LEVEL=DEBUG
# Observability (optional)
LOGFIRE_ENABLED=false
Test environment¶
Tests load .env.test automatically when it exists. If it does not, pytest falls
back to the committed .env.test.example defaults.
Running the application¶
Development servers¶
# Makefile
# FastAPI HTTP API
make dev
# Equivalent to: uv run uvicorn fastdjango.entrypoints.fastapi.app:app --reload --host 0.0.0.0 --port 8000
# Celery worker
make celery-dev
# Equivalent to the watched Celery worker command in the Makefile
# Celery beat scheduler
make celery-beat-dev
# Equivalent to the watched Celery beat command in the Makefile
Database operations¶
# management/manage.py
# Create migrations
make makemigrations
# Apply migrations
make migrate
# Or using Django manage.py directly
uv run python management/manage.py makemigrations
uv run python management/manage.py migrate
Testing¶
Running tests¶
# Makefile
# Run all tests with coverage
make test
# Run specific test file
pytest tests/integration/core/user/delivery/fastapi/test_controllers.py
# Run with verbose output
pytest -v tests/
# Run only unit tests
pytest tests/unit/
# Run with coverage report
pytest --cov=src --cov-report=html tests/
Test configuration¶
The default suite is self-contained: .env.test.example uses SQLite, and the
Celery test worker uses an in-memory broker/backend. Use PostgreSQL or Redis
only when you add project-specific integration tests that need those services.
The test fixtures automatically:
- Create isolated containers per test
- Roll back database transactions
- Clean up test data
Debugging¶
FastAPI debug mode¶
With DJANGO_DEBUG=true, the API documentation is available at:
- Swagger UI: http://localhost:8000/docs ReDoc is disabled in this template; use Swagger UI for interactive API testing.
Logging¶
Set LOGGING_LEVEL=DEBUG for verbose logging:
Celery debugging¶
For detailed Celery logs:
# src/fastdjango/entrypoints/celery/app.py
uv run celery -A fastdjango.entrypoints.celery.app worker --loglevel=debug
Docker development¶
Start local services¶
# docker/docker-compose.yaml
# Local Docker PostgreSQL and Redis
docker compose up -d postgres redis
# If you selected local MinIO storage
docker compose up -d minio
docker compose up minio-create-buckets
# Run migrations and collect static files with Dockerized app services
docker compose up migrations collectstatic
# Or run them from the host
make migrate
make collectstatic
# Full stack (including app)
docker compose up -d
For Django admin static files in Docker, ensure .env includes both:
AWS_S3_ENDPOINT_URL=http://minio:9000for app/container access.AWS_S3_PUBLIC_ENDPOINT_URL=http://localhost:9000for browser access.
View logs¶
# docker/docker-compose.yaml
# All services
docker compose logs -f
# Specific service
docker compose logs -f postgres
Reset local Docker data¶
# docker/docker-compose.yaml
docker compose down -v # Remove volumes
docker compose up -d postgres redis
# If you selected local MinIO storage
docker compose up -d minio
docker compose up minio-create-buckets
docker compose up migrations collectstatic