# 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