4.9 KiB
FastAPI Conventions Process
This file documents the workflow used to build and refine this repo so the extraction can be repeated without guesswork.
Goal
Turn repeated FastAPI-adjacent service patterns from mature upstream codebases into concise convention docs with verifiable citations.
Scope split
Keep this repo at the framework/service-boundary level.
Good fits:
- route shape and handler thinness
- dependency injection and request-scoped wiring
- request/response schema boundaries
- persistence/session handling in web services
- app lifespan and startup/shutdown wiring
- service testing at the HTTP/ASGI boundary
Do not re-document generic Python guidance here unless FastAPI meaningfully bends it.
Upstream selection rule
Use a mixed source set: framework internals plus at least one or two app-style repos.
Current first-wave set:
fastapi/fastapiencode/starlettepydantic/pydanticencode/httpx
Current refinement/app-layer set:
fastapi-users/fastapi-usersfastapi/full-stack-fastapi-template
Selection criteria:
- respected and maintained
- reveals real service-boundary behavior, not just toy usage
- enough tests/examples to show lifecycle and caveats
- includes both intended abstractions and pragmatic app wiring
Directory contract
sources/= raw evidence notes, one file per upstream repopatterns/= synthesized conventions from repeated evidencecomparison/= explicit notes on where FastAPI conventions differ from broader Python patterns
Step-by-step workflow
1) Separate framework conventions from Python-wide rules
That split keeps guidance crisp and prevents vague “it depends” docs.
2) Make upstream code available locally
Local checkouts make file:line verification cheap and keep the process grounded.
3) Write source notes first
For each upstream repo, create sources/<repo>.md with:
- why the repo was chosen
- repeated patterns
- caveats/counterexamples
- exact
file:linecitations - pattern candidates supported by the evidence
Good source notes are dense evidence, not polished guidance.
4) Synthesize conventions from the strongest repeated signals
Start with the topics where evidence is strongest.
In this repo that meant:
- routes
- dependencies
- errors
- testing
- pydantic boundaries
- persistence
Each convention doc should usually include:
- the convention
- why it exists
- where to apply it
- where not to cargo-cult it
- preferred shapes
- counterexamples
- source signals/citations
5) Add comparison notes where FastAPI bends general Python guidance
Examples:
- dependency injection via callables/signatures instead of constructor wiring
- request/response model boundaries as framework-facing objects
- lifespan hooks instead of generic entrypoint/context patterns
6) Refine before broadening
After the first useful convention set exists, do not rush to add more repos.
Instead:
- improve convention docs in fresh contexts
- strengthen citations
- rewrite
sources/*.mdso they are denser and more reusable - reduce duplicated guidance across docs
- preserve subtle framework caveats that are easy to flatten away
That was the right next move for this repo once the first source base existed.
Fresh-context refinement pattern
A good refinement split is:
- one fresh pass over convention docs
- one fresh pass over source-note files
- one fresh pass doing citation audit across both
Review checklist
For source notes
- Does the file distinguish repeated conventions from isolated examples?
- Does it preserve framework caveats and edge cases?
- Are citations exact and fast to verify?
- Does it avoid vague claims that are not source-backed?
For convention docs
- Is the guidance really FastAPI/service-boundary specific?
- Is the framework-owned behavior described at the right seam?
- Are testing and dependency recommendations grounded in actual code/tests?
- Are exceptions and tradeoffs preserved instead of erased?
Local git workflow used here
When the repo is ready for human review:
- initialize a local git repo
- stage the current documentation set
- create a single initial commit so review has a stable baseline
This repo intentionally avoids pushing or creating remotes unless explicitly requested.
How to repeat this process next time
- Define the scope split first.
- Pick a compact but high-signal upstream set.
- Build
sources/beforepatterns/. - Synthesize the strongest conventions first.
- Add comparison notes where the framework bends Python defaults.
- Run a fresh-context refinement wave.
- Initialize git only when the repo is reviewable.
What to avoid
- documenting FastAPI from memory or tutorial vibes
- mixing Python-wide guidance into this repo
- broadening source coverage before tightening evidence quality
- flattening dependency/lifespan/testing caveats into one-size-fits-all rules
- weak citations that are annoying to re-check