Factory.ai

Open-Source Wikis

/

FastAPI

/

Systems

/

Encoders

fastapi/fastapi

Encoders

Purpose

fastapi/encoders.py is a single module exposing jsonable_encoder — the function that converts arbitrary Python values into JSON-compatible primitives. It is used internally for response bodies (when going through a Starlette JSONResponse), error payloads, and any time the framework needs to hand a rich Python object to a stdlib JSON encoder.

Key abstractions

Symbol Purpose
jsonable_encoder(obj, *, include, exclude, by_alias, exclude_unset, exclude_defaults, exclude_none, custom_encoder, sqlalchemy_safe) Recursively converts the input to a tree of primitives.
ENCODERS_BY_TYPE A dict mapping type → encoder function. Pre-populated for bytes, Color, datetime, Decimal, Enum, IPv4*, IPv6*, Path, Pattern, set, UUID, etc.
decimal_encoder Returns int if the Decimal exponent is non-negative, otherwise float — preserves round-tripping.
isoformat Wrapper around datetime.date.isoformat / datetime.time.isoformat.
is_pydantic_v1_model_instance (re-exported from _compat) Used to gate Pydantic v1 detection — raising PydanticV1NotSupportedError if encountered.

How it works

The function is a recursive walk:

  1. If obj is a Pydantic v2 BaseModel, call its .model_dump(...) with the requested include/exclude/alias flags and recurse.
  2. If obj is a Pydantic v1 model, raise PydanticV1NotSupportedError.
  3. If obj is a dataclass (and not yet handled), convert via dataclasses.asdict and recurse.
  4. If obj is None, str, int, float, bool — return as-is.
  5. If obj is a dict, recurse on key/value pairs (keys go through the encoder too).
  6. If obj is a list/tuple/set/GeneratorType/deque/frozenset, return a list of encoded items.
  7. If obj's type is in ENCODERS_BY_TYPE or custom_encoder, apply the encoder.
  8. Otherwise try a few fallback paths (vars(obj) → recurse) and finally raise.

The flags mirror Pydantic's model_dump:

  • by_alias — emit field aliases (matches what OpenAPI declares).
  • exclude_unset — only include fields explicitly set on the model.
  • exclude_defaults — drop fields equal to their default.
  • exclude_none — drop None values.
  • include / exclude — set/dict of field paths to keep or drop.
  • custom_encoder — caller-supplied per-type overrides.
  • sqlalchemy_safe — when True, drop SQLAlchemy internal attributes from __dict__-walked objects.

Usage in the framework

  • Default exception handlers (fastapi/exception_handlers.py) call jsonable_encoder(exc.errors()) so validation errors render cleanly.
  • fastapi/openapi/utils.py:get_openapi_security_definitions encodes the SecurityBase.model for the OpenAPI document.
  • serialize_response (fastapi/routing.py) prefers a Pydantic-direct fast path but falls back to jsonable_encoder for arbitrary return values when no response_model is set and the response is JSON.

Integration points

  • Down to PydanticBaseModel.model_dump does the per-field work for models. The encoder mediates between Pydantic and stdlib JSON.
  • Down to _compat.is_pydantic_v1_model_instance — raises a clear error rather than silently producing the wrong shape.
  • Up to user codejsonable_encoder is part of the public API: from fastapi.encoders import jsonable_encoder.

Entry points for modification

  • Adding support for a new type: register in ENCODERS_BY_TYPE (or document custom_encoder).
  • Adding a new flag: thread through the recursive function and through Pydantic's model_dump call.
  • Changing handling for SQLAlchemy attributes: edit the sqlalchemy_safe branch.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Encoders – FastAPI wiki | Factory