Coding Standards & Style Guides
Fleet-wide Python standards extend PEP 8 with typing rules, project layout, error handling, and review expectations - enforced by Ruff 0.9+, pyright on changed paths, and templates new repos copy.
Recipe
Quick-reference recipe card - copy-paste ready.
# pyproject.toml (fleet baseline)
[tool.ruff]
line-length = 100
target-version = "py314"
select = ["E", "F", "I", "UP", "B", "ASYNC", "S"]
[tool.pyright]
pythonVersion = "3.14"
typeCheckingMode = "standard"src/<package>/
api/ # HTTP only
domain/ # no FastAPI/Django imports
infra/ # DB, queues, external IOWhen to reach for this:
- New service bootstrap
- PR debates repeating same style arguments
- Security audit asks for consistency
- Onboarding checklist
Working Example
"""domain/orders.py - meets fleet standards."""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
@dataclass(frozen=True)
class OrderTotal:
subtotal: Decimal
tax: Decimal
@property
def grand_total(self) -> Decimal:
return self.subtotal + self.tax
def compute_total(subtotal: Decimal, tax_rate: Decimal) -> OrderTotal:
tax = (subtotal * tax_rate).quantize(Decimal("0.01"))
return OrderTotal(subtotal=subtotal, tax=tax)# api/routes/orders.py - thin boundary
from fastapi import APIRouter
from pydantic import BaseModel
from domain.orders import compute_total
router = APIRouter()
class TotalRequest(BaseModel):
subtotal: float
tax_rate: float
@router.post("/total")
def total(body: TotalRequest) -> dict[str, float]:
result = compute_total(body.subtotal, body.tax_rate)
return {"grand_total": float(result.grand_total)}What this demonstrates:
- Domain module has types and no framework imports
- Money uses Decimal in domain; float only at HTTP boundary with explicit conversion policy
- Router stays thin; business rules testable without HTTP
- Standards align with reference SaaS layout
Deep Dive
How It Works
- Automate nits - Ruff format + lint in CI; humans review design.
- Typing - Public functions annotated;
Anyrequires comment justification. - Imports - isort via Ruff; no star imports in production code.
- Errors - Custom exception hierarchy per service; no bare
except. - Security - Bandit/S rules in Ruff for common issues.
Standards Beyond PEP 8
| Topic | Fleet rule |
|---|---|
| Async | No blocking I/O in async def without to_thread |
| SQL | Parameterized queries; ORM preferred |
| Logging | structlog JSON; no f-string in log message |
| Tests | pytest; fixtures over global state |
| Config | pydantic-settings; no raw os.environ scatter |
Python Notes
uv run ruff check .
uv run ruff format --check .
uv run pyright src/Gotchas
- 100% style perfection before features - Velocity dies. Fix: Automate; grandfather legacy with changed-path strictness.
- Inconsistent repo templates - Every service different. Fix: Cookiecutter internal template updated quarterly.
- Decimal everywhere in JSON - Serialization pain. Fix: Policy: Decimal domain, float/ str at API with validation.
- Ignoring ASYNC rules - Incidents later. Fix: ASYNC in default Ruff select.
- Standards doc unread - Link from PR template and linter messages.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Black only (no Ruff) | Legacy | New fleet (Ruff replaces both) |
| strict mypy entire repo | Greenfield tiny | Large legacy monolith |
| Google style guide verbatim | Need external reference | Fleet has custom layout |
| No standards | Imminent shutdown | Active multi-squad fleet |
FAQs
PEP 8 vs fleet guide?
PEP 8 baseline; fleet adds layout, typing, async, security rules.
Line length 88 or 100?
This fleet uses 100; pick one org-wide.
Django exceptions?
Allow Django imports in apps/ and services/ layers per Django template ADR.
Notebook standards?
Notebooks not in prod path; promoted code must pass same lint in modules.
Grandfather untyped code?
Yes; new modules typed; changed-path gate in CI.
Who updates standards?
Platform guild quarterly; RFC for controversial changes.
fmt on save?
Recommended; CI is source of truth.
Third-party generated code?
Exclude in ruff per-file-ignores; document paths.
Docstring style?
Google or NumPy style one choice; enforced in new code optionally.
Link to PEP 8 article?
Related
- Documentation Conventions - docs standards
- Contribution Guidelines - PR process
- Linting & Formatting - tooling
- Type Hints Best Practices - typing depth
- Python Rules - rule list
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.