Skip to content

OpenAPI & Encoding

Schema generation and the JSON encoding layer.

jsonable_encoder

jsonable_encoder(obj: Any, include: set[str] | None = None, exclude: set[str] | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, custom_encoder: dict[type, Callable[[Any], Any]] | None = None, *, _seen: set[int] | None = None) -> Any

Convert complex objects to JSON-serializable types.

Handles Pydantic models, dataclasses, datetime, Decimal, UUID, Enum, Path, sets, frozensets, and nested structures.

include / exclude apply to dict keys at every depth - passing exclude={"password"} strips a password key wherever it appears in the structure, not only at the top level. exclude_none likewise drops None-valued keys from plain dicts at every depth, not only from a top-level model's own fields.

Raises ValueError on a self-referential object graph (a container that transitively contains itself) instead of recursing until the stack overflows. Detection is by id(); the per-call _seen set is internal and should not be passed by callers.

custom_encoder is an optional {type: fn} mapping consulted before every built-in rule at every depth: the exact type(obj) wins, else the entries are scanned in insertion order returning the first isinstance match. Because it runs first it can override container and model handling as well as leaf scalars. Types registered process-wide via register_encoder are consulted later (after the exact-type fast paths) and cover subclasses through an MRO walk.

Usage::

data = jsonable_encoder(my_pydantic_model, exclude={"password"})

register_encoder

register_encoder(type_: type, encoder: Callable[[Any], Any]) -> None

Register a process-level JSON encoder for type_ and its subclasses.

encoder receives one instance and must return a JSON-able value (str/int/float/bool/None or a list/dict of such). It is consulted by jsonable_encoder after the exact-type fast paths, resolved via an MRO walk so subclasses of type_ are covered too. Registering a type that already has a built-in handler overrides that handler for the type and its subclasses.

Usage::

register_encoder(MyId, lambda v: v.hex)

unregister_encoder

unregister_encoder(type_: type) -> None

Remove a previously registered encoder for type_.

No-op if type_ was never registered.

JSONProvider

Base class for JSON serialisation providers.

Subclass to plug in an alternative serialiser, then point the app at it via app.json (an instance) or app.json_provider_class (a class, instantiated lazily on first access).

Usage::

class MyJSONProvider(JSONProvider):
    def dumps(self, obj, **kwargs):
        return my_lib.dumps(obj).encode()

    def loads(self, data):
        return my_lib.loads(data)

app.json_provider_class = MyJSONProvider

dumps

dumps(obj: Any, **kwargs: Any) -> bytes

Serialise obj to JSON bytes. Subclasses override.

Returns bytes (not str) so callers can write directly to a response body without re-encoding. The kwargs catch-all is provider-specific (e.g. indent=2, sort_keys=True).

loads

loads(data: bytes | str) -> Any

Parse JSON data into Python objects.

response

response(value: Any, **kwargs: Any) -> Any

Build a Response carrying value as JSON.

The default implementation delegates to dumps and wraps the result in a JSONResponse.

DefaultJSONProvider

Bases: JSONProvider

orjson-backed provider — Veloce's default.

Honours two app.config flags so the existing JSON_SORT_KEYS / JSONIFY_PRETTYPRINT_REGULAR toggles keep working without callers needing to subclass.

response

response(value: Any, **kwargs: Any) -> Any

Build a Response carrying value as JSON.

The default implementation delegates to dumps and wraps the result in a JSONResponse.

config_orjson_options

config_orjson_options(cfg: Any) -> int

Build the orjson option bitmask from an app config mapping.

Reads the JSON_SORT_KEYS and JSONIFY_PRETTYPRINT_REGULAR flags. Shared by DefaultJSONProvider and helpers.jsonify so the two paths cannot drift. Returns 0 when cfg is None.

get_openapi_schema

get_openapi_schema(app: Any) -> dict[str, Any]

Generate OpenAPI 3.1 schema from the app's registered routes.

setup_openapi_routes

setup_openapi_routes(app: Any, openapi_url: str = '/openapi.json', docs_url: str | None = '/docs', redoc_url: str | None = '/redoc') -> None

Register OpenAPI schema and documentation routes.

docs_url / redoc_url of None disable the Swagger UI / ReDoc UI respectively - the JSON schema route is still registered, so tooling can consume the schema without a public interactive explorer.