FastAPI Guidelines
by Convext
FastAPI coding patterns and best practices
Rules (56)
Config
Config in env vars, not code. Never commit .env. Commit .env.example. Never hardcode secrets.
Database
Passwords: bcrypt. API keys: encrypt. PII: field-level encryption. Never log sensitive data.
Dependencies
Use latest stable versions. Fix breaking changes—don't avoid upgrades. Check official registries.
Django
DRF serializers for validation. ViewSets for CRUD. Token/JWT auth. Pagination on list endpoints.
select_related/prefetch_related for joins. Use F() and Q() objects. Avoid N+1 with django-debug-toolbar.
One migration per change. Never edit applied migrations. Use RunPython for data migrations. Squash when large.
Forms/ModelForms for input validation. Clean methods for business logic. Never trust request.POST directly.
Fastapi
Use `Depends()` for db sessions, auth, config, services. Composable and testable.
Async drivers: asyncpg (Postgres), SQLAlchemy 2.0 async. Match FastAPI's async nature.
Explicit Pydantic models for all inputs/outputs. Auto-validation, docs, type safety.
Flask
`create_app()` factory pattern. Config from env. Blueprints for modularity. Flask extensions for features.
Flask-SQLAlchemy for ORM. Flask-Migrate for migrations. Scoped sessions. Avoid circular imports.
Formatting
isort for import ordering. Profile: black. Run before Black. Or use Ruff which includes isort.
Git
Small, focused commits. Use: feat/fix/refactor/test/docs/chore. Each commit independently deployable.
Linting
mypy with --strict mode. Check all files. Fix type errors, don't ignore. Part of CI pipeline.
pyright: fast type checker. VS Code Pylance backend. strict or basic mode. Better inference than mypy.
flake8 for style checks. Use with .flake8 config. max-line-length: 88 (Black compat). Ruff is faster alternative.
Llm Behavior
No excuses: 'pre-existing', 'unrelated', 'tedious', 'for now'. Recognize and continue working.
You wrote every line. No 'pre-existing issues'—only issues you haven't fixed yet.
User and tests define done. Don't redefine scope or declare partial progress as complete.
Package Manager
requirements.txt with pinned versions. `pip freeze > requirements.txt`. Virtual environments. Prefer uv.
pyproject.toml + poetry.lock. `poetry install --no-dev` for prod. Groups for dev deps. Prefer uv for speed.
Python
Use `uv` (not pip/poetry/pipenv). 100x faster, lockfile support, built-in venv. Commands: `uv add`, `uv run`.
Type hints on all functions and class attributes. Enables mypy/pyright static analysis.
Ruff for both linting and formatting (replaces flake8/isort/pylint/Black). Single tool, 100x faster. `ruff check` and `ruff format`.
logging module, not print. Configure at app entry point. Use __name__ for logger names. Structured logging with extra dict or structlog.
with statement for files, connections, locks. contextlib for custom managers. Never leave resources open. async with for async resources.
Async for HTTP (httpx), database (asyncpg), files (aiofiles). Don't mix sync/async in same service.
Pydantic BaseModel for validation. Field types with constraints. Serialization built-in. FastAPI integration.
SQLAlchemy 2.0 style. Declarative models. Session management. Async with asyncio extension.
pyproject.toml for deps, uv.lock (commit it), .python-version, src/ layout. Python 3.12+.
Alembic for SQLAlchemy migrations. `alembic revision --autogenerate`. Review generated migrations. Stamp for sync.
boto3 for AWS services. Use resource API for simple ops, client for advanced. Handle pagination.
Dataclasses for simple containers, Pydantic for validation. No plain dicts for structured data.
Define entry points in `[project.scripts]`. Run any command with `uv run <cmd>`. CI: `uv sync --frozen`.
Use `[tool.uv.workspace]` for multi-package repos. Single lockfile, editable local packages.
pytest with fixtures and parametrize. Simple asserts, rich plugin ecosystem.
Celery for distributed task queue. Redis or RabbitMQ broker. Beat for scheduling. Flower for monitoring.
pipenv is slow and unmaintained. Migrate to uv for speed and modern features. `uv init` from existing.
unittest for simple cases or legacy code. TestCase classes. setUp/tearDown. Prefer pytest for new projects.
pylint for comprehensive checks. Disable noisy rules in pylintrc. Ruff is faster alternative.
httpx for async HTTP client. Requests-compatible API. Async context manager. HTTP/2 support.
requests for simple sync HTTP. Session for connection pooling. Timeout always. Use httpx for async.
Rails
Rails.application.credentials for secrets. `rails credentials:edit`. Environment-specific credentials. Never commit master.key.
Security
Allowlists, not denylists. Validate type/length/format. Sanitize HTML. Parameterized queries only.
Force SSL, redirect HTTP→HTTPS, secure cookies (Secure/HttpOnly/SameSite), HSTS headers.
Auth: bcrypt/argon2 for passwords, rate limiting, secure sessions/tokens. Authz: check permissions on every request, use policy objects or middleware.
Testing
Test real instances. Mocking the class under test hides bugs.
Fix failures immediately. No skipping, no "pre-existing issues." Own the codebase state—a test suite with ignored tests can't be trusted.
1) Write failing test 2) Minimum code to pass 3) Refactor. Every line has a reason.
Test public interfaces, inputs/outputs. Tests must survive refactoring. Don't test private methods.
Mock only: external HTTP APIs, time, filesystem side effects, third-party services. Use real implementations for internal services, database, and business logic.
One logical concept per test. Multiple asserts OK if same concept. Clear test names describing behavior.
Use consistent test data setup: fixtures for stable reference data, factories for dynamic scenarios. Avoid inline object creation scattered throughout tests.
Workflow
Verify changes locally: run app, run tests, check for errors. CI catches environment issues, not basic bugs.
Format → Lint → Test before every commit. Never rely on CI for basic checks.
Language Standards (1)
Use this Ruleset
Sign in to adopt or fork this ruleset
Sign in with GitHubStatistics
- Rules
- 56
- Standards
- 1
- Projects using
- 0
- Created
- Jan 15, 2026