Pydantic allows auto creation of JSON Schemas from models:
{!.tmp_examples/schema_main.py!}
(This script is complete, it should run "as is")
Outputs:
{!.tmp_examples/schema_main.json!}
The generated schemas are compliant with the specifications: JSON Schema Core, JSON Schema Validation and OpenAPI.
BaseModel.schema
will return a dict of the schema, while BaseModel.schema_json
will return a JSON string
representation of that dict.
Sub-models used are added to the definitions
JSON attribute and referenced, as per the spec.
All sub-models' (and their sub-models') schemas are put directly in a top-level definitions
JSON key for easy re-use
and reference.
"Sub-models" with modifications (via the Field
class) like a custom title, description or default value,
are recursively included instead of referenced.
The description
for models is taken from either the docstring of the class or the argument description
to
the Field
class.
The schema is generated by default using aliases as keys, but it can be generated using model
property names instead by calling MainModel.schema/schema_json(by_alias=False)
.
Optionally, the Field
function can be used to provide extra information about the field and validations.
It has the following arguments:
-
default
: (a positional argument) the default value of the field. Since theField
replaces the field's default, this first argument can be used to set the default. Use ellipsis (...
) to indicate the field is required. -
default_factory
: a zero-argument callable that will be called when a default value is needed for this field. Among other purposes, this can be used to set dynamic default values. It is forbidden to set bothdefault
anddefault_factory
. -
alias
: the public name of the field -
title
: if omitted,field_name.title()
is used -
description
: if omitted and the annotation is a sub-model, the docstring of the sub-model will be used -
const
: this argument must be the same as the field's default value if present. -
gt
: for numeric values (int
,float
,Decimal
), adds a validation of "greater than" and an annotation ofexclusiveMinimum
to the JSON Schema -
ge
: for numeric values, this adds a validation of "greater than or equal" and an annotation ofminimum
to the JSON Schema -
lt
: for numeric values, this adds a validation of "less than" and an annotation ofexclusiveMaximum
to the JSON Schema -
le
: for numeric values, this adds a validation of "less than or equal" and an annotation ofmaximum
to the JSON Schema -
multiple_of
: for numeric values, this adds a validation of "a multiple of" and an annotation ofmultipleOf
to the JSON Schema -
min_items
: for list values, this adds a corresponding validation and an annotation ofminItems
to the JSON Schema -
max_items
: for list values, this adds a corresponding validation and an annotation ofmaxItems
to the JSON Schema -
min_length
: for string values, this adds a corresponding validation and an annotation ofminLength
to the JSON Schema -
max_length
: for string values, this adds a corresponding validation and an annotation ofmaxLength
to the JSON Schema -
regex
: for string values, this adds a Regular Expression validation generated from the passed string and an annotation ofpattern
to the JSON Schema!!! note pydantic validates strings using
re.match
, which treats regular expressions as implicitly anchored at the beginning. On the contrary, JSON Schema validators treat thepattern
keyword as implicitly unanchored, more like whatre.search
does.For interoperability, depending on your desired behavior, either explicitly anchor your regular expressions with `^` (e.g. `^foo` to match any string starting with `foo`), or explicitly allow an arbitrary prefix with `.*?` (e.g. `.*?foo` to match any string containing the substring `foo`). See [#1631](https://github.com/samuelcolvin/pydantic/issues/1631) for a discussion of possible changes to *pydantic* behavior in **v2**.
-
**
any other keyword arguments (e.g.examples
) will be added verbatim to the field's schema
Instead of using Field
, the fields
property of the Config class can be used
to set all of the arguments above except default
.
If pydantic finds constraints which are not being enforced, an error will be raised. If you want to force the
constraint to appear in the schema, even though it's not being checked upon parsing, you can use variadic arguments
to Field()
with the raw schema attribute name:
{!.tmp_examples/schema_unenforced_constraints.py!}
(This script is complete, it should run "as is")
Custom field types can customise the schema generated for them using the __modify_schema__
class method;
see Custom Data Types for more details.
Types, custom field types, and constraints (like max_length
) are mapped to the corresponding spec formats in the
following priority order (when there is an equivalent available):
- JSON Schema Core
- JSON Schema Validation
- OpenAPI Data Types
- The standard
format
JSON field is used to define pydantic extensions for more complexstring
sub-types.
The field schema mapping from Python / pydantic to JSON Schema is done as follows:
{!.tmp_schema_mappings.html!}
You can also generate a top-level JSON Schema that only includes a list of models and related
sub-models in its definitions
:
{!.tmp_examples/schema_top_level.py!}
(This script is complete, it should run "as is")
Outputs:
{!.tmp_examples/schema_top_level.json!}
You can customize the generated $ref
JSON location: the definitions are always stored under the key
definitions
, but a specified prefix can be used for the references.
This is useful if you need to extend or modify the JSON Schema default definitions location. E.g. with OpenAPI:
{!.tmp_examples/schema_custom.py!}
(This script is complete, it should run "as is")
Outputs:
{!.tmp_examples/schema_custom.json!}
It's also possible to extend/override the generated JSON schema in a model.
To do it, use the Config
sub-class attribute schema_extra
.
For example, you could add examples
to the JSON Schema:
{!.tmp_examples/schema_with_example.py!}
(This script is complete, it should run "as is")
Outputs:
{!.tmp_examples/schema_with_example.json!}
For more fine-grained control, you can alternatively set schema_extra
to a callable and post-process the generated schema.
The callable can have one or two positional arguments.
The first will be the schema dictionary.
The second, if accepted, will be the model class.
The callable is expected to mutate the schema dictionary in-place; the return value is not used.
For example, the title
key can be removed from the model's properties
:
{!.tmp_examples/schema_extra_callable.py!}
(This script is complete, it should run "as is")
Outputs:
{!.tmp_examples/schema_extra_callable.json!}