The primary means of defining objects in *pydantic* is via models (models are simply classes which inherit from `BaseModel`). You can think of models as similar to types in strictly typed languages, or as the requirements of a single endpoint in an API. Untrusted data can be passed to a model, and after parsing and validation *pydantic* guarantees that the fields of the resultant model instance will conform to the field types defined on the model. !!! note *pydantic* is primarily a parsing library, **not a validation library**. Validation is a means to an end: building a model which conforms to the types and constraints provided. In other words, *pydantic* guarantees the types and constraints of the output model, not the input data. This might sound like an esoteric distinction, but it is not. If you're unsure what this means or how it might affect your usage you should read the section about [Data Conversion](#data-conversion) below. Although validation is not the main purpose of *pydantic*, you **can** use this library for custom [validation](validators.md). ## Basic model usage ```py from pydantic import BaseModel class User(BaseModel): id: int name = 'Jane Doe' ``` `User` here is a model with two fields `id` which is an integer and is required, and `name` which is a string and is not required (it has a default value). The type of `name` is inferred from the default value, and so a type annotation is not required (however note [this](#field-ordering) warning about field order when some fields do not have type annotations). ```py user = User(id='123') user_x = User(id='123.45') ``` `user` here is an instance of `User`. Initialisation of the object will perform all parsing and validation, if no `ValidationError` is raised, you know the resulting model instance is valid. ```py assert user.id == 123 assert user_x.id == 123 assert isinstance(user_x.id, int) # Note that 123.45 was casted to an int and its value is 123 ``` More details on the casting in the case of `user_x` can be found in [Data Conversion](#data-conversion). Fields of a model can be accessed as normal attributes of the user object. The string '123' has been cast to an int as per the field type ```py assert user.name == 'Jane Doe' ``` `name` wasn't set when user was initialised, so it has the default value ```py assert user.__fields_set__ == {'id'} ``` The fields which were supplied when user was initialised. ```py assert user.model_dump() == dict(user) == {'id': 123, 'name': 'Jane Doe'} ``` Either `.model_dump()` or `dict(user)` will provide a dict of fields, but `.model_dump()` can take numerous other arguments. ```py user.id = 321 assert user.id == 321 ``` This model is mutable so field values can be changed. ### Model properties The example above only shows the tip of the iceberg of what models can do. Models possess the following methods and attributes: `model_dump()` : returns a dictionary of the model's fields and values; cf. [exporting models](exporting_models.md#modeldict) `model_dump_json()` : returns a JSON string representation `model_dump()`; cf. [exporting models](exporting_models.md#modeljson) `copy()` : returns a copy (by default, shallow copy) of the model; cf. [exporting models](exporting_models.md#modelcopy) `model_validate()` : a utility for loading any object into a model with error handling if the object is not a dictionary; cf. [helper functions](#helper-functions) `parse_raw()` : a utility for loading strings of numerous formats; cf. [helper functions](#helper-functions) `parse_file()` : like `parse_raw()` but for file paths; cf. [helper functions](#helper-functions) `from_orm()` : loads data into a model from an arbitrary class; cf. [ORM mode](#orm-mode-aka-arbitrary-class-instances) `model_json_schema()` : returns a dictionary representing the model as JSON Schema; cf. [schema](schema.md) `schema_json()` : returns a JSON string representation of `schema()`; cf. [schema](schema.md) `model_construct()` : a class method for creating models without running validation; cf. [Creating models without validation](#creating-models-without-validation) `__fields_set__` : Set of names of fields which were set when the model instance was initialised `model_fields` : a dictionary of the model's fields `__config__` : the configuration class for the model, cf. [model config](model_config.md) ## Recursive Models More complex hierarchical data structures can be defined using models themselves as types in annotations. {!.tmp_examples/models_recursive.md!} For self-referencing models, see [postponed annotations](postponed_annotations.md#self-referencing-models). ## ORM Mode (aka Arbitrary Class Instances) Pydantic models can be created from arbitrary class instances to support models that map to ORM objects. To do this: 1. The [Config](model_config.md) property `orm_mode` must be set to `True`. 2. The special constructor `from_orm` must be used to create the model instance. The example here uses SQLAlchemy, but the same approach should work for any ORM. {!.tmp_examples/models_orm_mode.md!} ### Reserved names You may want to name a Column after a reserved SQLAlchemy field. In that case, Field aliases will be convenient: {!.tmp_examples/models_orm_mode_reserved_name.md!} !!! note The example above works because aliases have priority over field names for field population. Accessing `SQLModel`'s `metadata` attribute would lead to a `ValidationError`. ### Recursive ORM models ORM instances will be parsed with `from_orm` recursively as well as at the top level. Here a vanilla class is used to demonstrate the principle, but any ORM class could be used instead. {!.tmp_examples/models_orm_mode_recursive.md!} ### Data binding Arbitrary classes are processed by *pydantic* using the `GetterDict` class (see [utils.py](https://github.com/pydantic/pydantic/blob/main/pydantic/utils.py)), which attempts to provide a dictionary-like interface to any class. You can customise how this works by setting your own sub-class of `GetterDict` as the value of `Config.getter_dict` (see [config](model_config.md)). You can also customise class validation using [root_validators](validators.md#root-validators) with `pre=True`. In this case your validator function will be passed a `GetterDict` instance which you may copy and modify. The `GetterDict` instance will be called for each field with a sentinel as a fallback (if no other default value is set). Returning this sentinel means that the field is missing. Any other value will be interpreted as the value of the field. {!.tmp_examples/models_orm_mode_data_binding.md!} ## Error Handling *pydantic* will raise `ValidationError` whenever it finds an error in the data it's validating. !!! note Validation code should not raise `ValidationError` itself, but rather raise `ValueError`, `TypeError` or `AssertionError` (or subclasses of `ValueError` or `TypeError`) which will be caught and used to populate `ValidationError`. One exception will be raised regardless of the number of errors found, that `ValidationError` will contain information about all the errors and how they happened. You can access these errors in several ways: `e.errors()` : method will return list of errors found in the input data. `e.json()` : method will return a JSON representation of `errors`. `str(e)` : method will return a human readable representation of the errors. Each error object contains: `loc` : the error's location as a list. The first item in the list will be the field where the error occurred, and if the field is a [sub-model](models.md#recursive-models), subsequent items will be present to indicate the nested location of the error. `type` : a computer-readable identifier of the error type. `msg` : a human readable explanation of the error. `ctx` : an optional object which contains values required to render the error message. As a demonstration: {!.tmp_examples/models_errors1.md!} ### Custom Errors In your custom data types or validators you should use `ValueError`, `TypeError` or `AssertionError` to raise errors. See [validators](validators.md) for more details on use of the `@validator` decorator. {!.tmp_examples/models_errors2.md!} You can also define your own error classes, which can specify a custom error code, message template, and context: {!.tmp_examples/models_errors3.md!} ## Helper Functions *Pydantic* provides three `classmethod` helper functions on models for parsing data: * **`model_validate`**: this is very similar to the `__init__` method of the model, except it takes a dict rather than keyword arguments. If the object passed is not a dict a `ValidationError` will be raised. * **`parse_raw`**: this takes a *str* or *bytes* and parses it as *json*, then passes the result to `model_validate`. Parsing *pickle* data is also supported by setting the `content_type` argument appropriately. * **`parse_file`**: this takes in a file path, reads the file and passes the contents to `parse_raw`. If `content_type` is omitted, it is inferred from the file's extension. {!.tmp_examples/models_parse.md!} !!! warning To quote the [official `pickle` docs](https://docs.python.org/3/library/pickle.html), "The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source." !!! info Because it can result in arbitrary code execution, as a security measure, you need to explicitly pass `allow_pickle` to the parsing function in order to load `pickle` data. ### Creating models without validation *pydantic* also provides the `model_construct()` method which allows models to be created **without validation** this can be useful when data has already been validated or comes from a trusted source and you want to create a model as efficiently as possible (`model_construct()` is generally around 30x faster than creating a model with full validation). !!! warning `model_construct()` does not do any validation, meaning it can create models which are invalid. **You should only ever use the `model_construct()` method with data which has already been validated, or you trust.** {!.tmp_examples/models_construct.md!} The `_fields_set` keyword argument to `model_construct()` is optional, but allows you to be more precise about which fields were originally set and which weren't. If it's omitted `__fields_set__` will just be the keys of the data provided. For example, in the example above, if `_fields_set` was not provided, `new_user.__fields_set__` would be `{'id', 'age', 'name'}`. ## Generic Models Pydantic supports the creation of generic models to make it easier to reuse a common model structure. In order to declare a generic model, you perform the following steps: * Declare one or more `typing.TypeVar` instances to use to parameterize your model. * Declare a pydantic model that inherits from `pydantic.generics.GenericModel` and `typing.Generic`, where you pass the `TypeVar` instances as parameters to `typing.Generic`. * Use the `TypeVar` instances as annotations where you will want to replace them with other types or pydantic models. Here is an example using `GenericModel` to create an easily-reused HTTP response payload wrapper: {!.tmp_examples/models_generics.md!} If you set `Config` or make use of `validator` in your generic model definition, it is applied to concrete subclasses in the same way as when inheriting from `BaseModel`. Any methods defined on your generic class will also be inherited. Pydantic's generics also integrate properly with mypy, so you get all the type checking you would expect mypy to provide if you were to declare the type without using `GenericModel`. !!! note Internally, pydantic uses `create_model` to generate a (cached) concrete `BaseModel` at runtime, so there is essentially zero overhead introduced by making use of `GenericModel`. To inherit from a GenericModel without replacing the `TypeVar` instance, a class must also inherit from `typing.Generic`: {!.tmp_examples/models_generics_inheritance.md!} You can also create a generic subclass of a `GenericModel` that partially or fully replaces the type parameters in the superclass. {!.tmp_examples/models_generics_inheritance_extend.md!} If the name of the concrete subclasses is important, you can also override the default behavior: {!.tmp_examples/models_generics_naming.md!} Using the same TypeVar in nested models allows you to enforce typing relationships at different points in your model: {!.tmp_examples/models_generics_nested.md!} Pydantic also treats `GenericModel` similarly to how it treats built-in generic types like `List` and `Dict` when it comes to leaving them unparameterized, or using bounded `TypeVar` instances: * If you don't specify parameters before instantiating the generic model, they will be treated as `Any` * You can parametrize models with one or more *bounded* parameters to add subclass checks Also, like `List` and `Dict`, any parameters specified using a `TypeVar` can later be substituted with concrete types. {!.tmp_examples/models_generics_typevars.md!} ## Dynamic model creation There are some occasions where the shape of a model is not known until runtime. For this *pydantic* provides the `create_model` method to allow models to be created on the fly. {!.tmp_examples/models_dynamic_creation.md!} Here `StaticFoobarModel` and `DynamicFoobarModel` are identical. !!! warning See the note in [Required Optional Fields](#required-optional-fields) for the distinction between an ellipsis as a field default and annotation-only fields. See [pydantic/pydantic#1047](https://github.com/pydantic/pydantic/issues/1047) for more details. Fields are defined by either a tuple of the form `(, )` or just a default value. The special key word arguments `__config__` and `__base__` can be used to customise the new model. This includes extending a base model with extra fields. {!.tmp_examples/models_dynamic_inheritance.md!} You can also add validators by passing a dict to the `__validators__` argument. {!.tmp_examples/models_dynamic_validators.md!} ## Model creation from `NamedTuple` or `TypedDict` Sometimes you already use in your application classes that inherit from `NamedTuple` or `TypedDict` and you don't want to duplicate all your information to have a `BaseModel`. For this _pydantic_ provides `create_model_from_namedtuple` and `create_model_from_typeddict` methods. Those methods have the exact same keyword arguments as `create_model`. {!.tmp_examples/models_from_typeddict.md!} ## Custom Root Types Pydantic models can be defined with a custom root type by declaring the `__root__` field. The root type can be any type supported by pydantic, and is specified by the type hint on the `__root__` field. The root value can be passed to the model `__init__` via the `__root__` keyword argument, or as the first and only argument to `model_validate`. {!.tmp_examples/models_custom_root_field.md!} If you call the `model_validate` method for a model with a custom root type with a *dict* as the first argument, the following logic is used: * If the custom root type is a mapping type (eg., `Dict` or `Mapping`), the argument itself is always validated against the custom root type. * For other custom root types, if the dict has precisely one key with the value `__root__`, the corresponding value will be validated against the custom root type. * Otherwise, the dict itself is validated against the custom root type. This is demonstrated in the following example: {!.tmp_examples/models_custom_root_field_parse_obj.md!} !!! warning Calling the `model_validate` method on a dict with the single key `"__root__"` for non-mapping custom root types is currently supported for backwards compatibility, but is not recommended and may be dropped in a future version. If you want to access items in the `__root__` field directly or to iterate over the items, you can implement custom `__iter__` and `__getitem__` functions, as shown in the following example. {!.tmp_examples/models_custom_root_access.md!} ## Faux Immutability Models can be configured to be immutable via `allow_mutation = False`. When this is set, attempting to change the values of instance attributes will raise errors. See [model config](model_config.md) for more details on `Config`. !!! warning Immutability in Python is never strict. If developers are determined/stupid they can always modify a so-called "immutable" object. {!.tmp_examples/models_mutation.md!} Trying to change `a` caused an error, and `a` remains unchanged. However, the dict `b` is mutable, and the immutability of `foobar` doesn't stop `b` from being changed. ## Abstract Base Classes Pydantic models can be used alongside Python's [Abstract Base Classes](https://docs.python.org/3/library/abc.html) (ABCs). {!.tmp_examples/models_abc.md!} ## Field Ordering Field order is important in models for the following reasons: * validation is performed in the order fields are defined; [fields validators](validators.md) can access the values of earlier fields, but not later ones * field order is preserved in the model [schema](schema.md) * field order is preserved in [validation errors](#error-handling) * field order is preserved by [`.model_dump()` and `.model_dump_json()` etc.](exporting_models.md#modeldict) As of **v1.0** all fields with annotations (whether annotation-only or with a default value) will precede all fields without an annotation. Within their respective groups, fields remain in the order they were defined. {!.tmp_examples/models_field_order.md!} !!! warning As demonstrated by the example above, combining the use of annotated and non-annotated fields in the same model can result in surprising field orderings. (This is due to limitations of Python) Therefore, **we recommend adding type annotations to all fields**, even when a default value would determine the type by itself to guarantee field order is preserved. ## Required fields To declare a field as required, you may declare it using just an annotation, or you may use an ellipsis (`...`) as the value: {!.tmp_examples/models_required_fields.md!} Where `Field` refers to the [field function](schema.md#field-customization). Here `a`, `b` and `c` are all required. However, use of the ellipses in `b` will not work well with [mypy](mypy.md), and as of **v1.0** should be avoided in most cases. ### Required Optional fields !!! warning Since version **v1.2** annotation only nullable (`Optional[...]`, `Union[None, ...]` and `Any`) fields and nullable fields with an ellipsis (`...`) as the default value, no longer mean the same thing. In some situations this may cause **v1.2** to not be entirely backwards compatible with earlier **v1.*** releases. If you want to specify a field that can take a `None` value while still being required, you can use `Optional` with `...`: {!.tmp_examples/models_required_field_optional.md!} In this model, `a`, `b`, and `c` can take `None` as a value. But `a` is optional, while `b` and `c` are required. `b` and `c` require a value, even if the value is `None`. ## Field with dynamic default value When declaring a field with a default value, you may want it to be dynamic (i.e. different for each model). To do this, you may want to use a `default_factory`. !!! info "In Beta" The `default_factory` argument is in **beta**, it has been added to *pydantic* in **v1.5** on a **provisional basis**. It may change significantly in future releases and its signature or behaviour will not be concrete until **v2**. Feedback from the community while it's still provisional would be extremely useful; either comment on [#866](https://github.com/pydantic/pydantic/issues/866) or create a new issue. Example of usage: {!.tmp_examples/models_default_factory.md!} Where `Field` refers to the [field function](schema.md#field-customization). !!! warning The `default_factory` expects the field type to be set. ## Automatically excluded attributes Class variables which begin with an underscore and attributes annotated with `typing.ClassVar` will be automatically excluded from the model. ## Private model attributes If you need to vary or manipulate internal attributes on instances of the model, you can declare them using `PrivateAttr`: {!.tmp_examples/private_attributes.md!} Private attribute names must start with underscore to prevent conflicts with model fields: both `_attr` and `__attr__` are supported. If `Config.underscore_attrs_are_private` is `True`, any non-ClassVar underscore attribute will be treated as private: {!.tmp_examples/private_attributes_underscore_attrs_are_private.md!} Upon class creation pydantic constructs `__slots__` filled with private attributes. ## Parsing data into a specified type Pydantic includes a standalone utility function `parse_obj_as` that can be used to apply the parsing logic used to populate pydantic models in a more ad-hoc way. This function behaves similarly to `BaseModel.model_validate`, but works with arbitrary pydantic-compatible types. This is especially useful when you want to parse results into a type that is not a direct subclass of `BaseModel`. For example: {!.tmp_examples/parse_obj_as.md!} This function is capable of parsing data into any of the types pydantic can handle as fields of a `BaseModel`. Pydantic also includes two similar standalone functions called `parse_file_as` and `parse_raw_as`, which are analogous to `BaseModel.parse_file` and `BaseModel.parse_raw`. ## Data Conversion *pydantic* may cast input data to force it to conform to model field types, and in some cases this may result in a loss of information. For example: {!.tmp_examples/models_data_conversion.md!} This is a deliberate decision of *pydantic*, and in general it's the most useful approach. See [here](https://github.com/pydantic/pydantic/issues/578) for a longer discussion on the subject. Nevertheless, [strict type checking](types.md#strict-types) is partially supported. ## Model signature All *pydantic* models will have their signature generated based on their fields: {!.tmp_examples/models_signature.md!} An accurate signature is useful for introspection purposes and libraries like `FastAPI` or `hypothesis`. The generated signature will also respect custom `__init__` functions: {!.tmp_examples/models_signature_custom_init.md!} To be included in the signature, a field's alias or name must be a valid Python identifier. *pydantic* prefers aliases over names, but may use field names if the alias is not a valid Python identifier. If a field's alias and name are both invalid identifiers, a `**data` argument will be added. In addition, the `**data` argument will always be present in the signature if `Config.extra` is `Extra.allow`. !!! note Types in the model signature are the same as declared in model annotations, not necessarily all the types that can actually be provided to that field. This may be fixed one day once [#1055](https://github.com/pydantic/pydantic/issues/1055) is solved. ## Structural pattern matching *pydantic* supports structural pattern matching for models, as introduced by [PEP 636](https://peps.python.org/pep-0636/) in Python 3.10. {!.tmp_examples/models_structural_pattern_matching.md!} !!! note A match-case statement may seem as if it creates a new model, but don't be fooled; it is just syntactic sugar for getting an attribute and either comparing it or declaring and initializing it.