Files
fastapi-conventions/sources/pydantic.md
T
2026-06-01 21:42:05 +00:00

66 lines
4.2 KiB
Markdown

# Pydantic source notes for FastAPI conventions
Repo: `pydantic/pydantic`
Local checkout: `/home/ubuntu/repos/rodin-sources/pydantic`
## Why this repo was chosen
- FastAPI's request/response model layer is built on Pydantic. This repo is the right source for boundary-shaping rules: coercion, validation timing, explicit serialization, and validator failure modes.
- Important here because Pydantic's docs include both recommended patterns and dangerous counterexamples.
## Repeated patterns
### 1) Pydantic models are designed for transport boundaries: parse external input, then serialize explicitly
- `docs/index.md:61-89` shows raw external input being coerced into a typed `BaseModel`, including datetime parsing, bytes-to-string coercion, and string-to-int coercion.
- `docs/index.md:82-107` uses `model_dump()` as the explicit serialization boundary.
- `docs/index.md:109-152` shows invalid external data producing a structured `ValidationError` with per-field errors.
Why chosen:
- This is the front-door example in the docs and directly matches how FastAPI uses models for requests and responses.
Caveat / counterexample:
- `docs/index.md:93-104` makes clear that default validation is not strict-only; coercion is normal behavior. Any synthesized guidance that assumes "Pydantic means no coercion" would be wrong without an explicit strictness choice.
Implication for synthesis:
- Recommend models at the API boundary, but mention that Pydantic may coerce inputs unless strict behavior is configured.
- Prefer explicit `model_dump()`/response-model boundaries over ad hoc dict shaping deep in business logic.
### 2) Use field validators to keep domain-specific checks close to fields, and choose validator timing deliberately
- `docs/concepts/validators.md:38-45` defines the contract for field validators: they receive a value and must return the validated value.
- `docs/concepts/validators.md:46-80` shows after-validators as the type-safer default because they run after Pydantic's internal validation.
- `docs/concepts/validators.md:160-209` shows before-validators receiving raw input, making them useful for coercion/preprocessing before core parsing.
Why chosen:
- These are not isolated APIs; the docs frame validator timing as a central design choice.
Caveat / counterexample:
- `docs/concepts/validators.md:160-206` warns that before-validators must handle arbitrary raw input and should avoid unsafe mutation when later raising errors, especially with unions.
Implication for synthesis:
- Prefer after-validators for invariant checks on already-parsed values.
- Use before-validators only when the input truly needs normalization before parsing.
### 3) Not every validator mode is safe for API-boundary schemas
- `docs/concepts/validators.md:254-311` shows plain validators short-circuiting internal validation entirely; the example accepts `number='invalid'` even though the field is annotated as `int`.
- `docs/concepts/validators.md:313-320` explains that wrap validators can also bypass normal validation flow if they return early or skip the handler.
Why chosen:
- These are exactly the kinds of footguns that can quietly weaken FastAPI request validation if used casually.
Implication for synthesis:
- Avoid recommending plain/wrap validators as the default pattern for request models.
- If they appear in synthesized guidance, frame them as advanced escape hatches with validation-bypass risk.
## Strong citation candidates
- External data coercion + explicit serialization boundary: `docs/index.md:61-107`
- Validation errors are structured and field-specific: `docs/index.md:109-152`
- Validator contract and return-value requirement: `docs/concepts/validators.md:38-45`
- After-vs-before validator tradeoff: `docs/concepts/validators.md:46-80`, `docs/concepts/validators.md:160-209`
- Plain validators can accept invalid typed data: `docs/concepts/validators.md:254-311`
## Pattern candidates supported by this repo
- use Pydantic models at transport boundaries
- keep serialization explicit with `model_dump()` or response-model shaping
- prefer after-validators for parsed-value invariants
- use before-validators sparingly for raw-input normalization
- treat plain/wrap validators as advanced tools, not defaults for API schemas