Skip to content
You're viewing docs for v1.10. See the latest version →

Types

Where possible pydantic uses standard library types to define fields, thus smoothing the learning curve. For many useful applications, however, no standard library type exists, so pydantic implements many commonly used types.

If no existing type suits your purpose you can also implement your own pydantic-compatible types with custom properties and validation.

Standard Library Types

pydantic supports many common types from the Python standard library. If you need stricter processing see Strict Types; if you need to constrain the values allowed (e.g. to require a positive int) see Constrained Types.

None, type(None) or Literal[None] (equivalent according to PEP 484) : allows only None value

bool : see Booleans below for details on how bools are validated and what values are permitted

int : pydantic uses int(v) to coerce types to an int; see this warning on loss of information during data conversion

float : similarly, float(v) is used to coerce values to floats

str : strings are accepted as-is, int float and Decimal are coerced using str(v), bytes and bytearray are converted using v.decode(), enums inheriting from str are converted using v.value, and all other types cause an error

bytes : bytes are accepted as-is, bytearray is converted using bytes(v), str are converted using v.encode(), and int, float, and Decimal are coerced using str(v).encode()

list : allows list, tuple, set, frozenset, deque, or generators and casts to a list; see typing.List below for sub-type constraints

tuple : allows list, tuple, set, frozenset, deque, or generators and casts to a tuple; see typing.Tuple below for sub-type constraints

dict : dict(v) is used to attempt to convert a dictionary; see typing.Dict below for sub-type constraints

set : allows list, tuple, set, frozenset, deque, or generators and casts to a set; see typing.Set below for sub-type constraints

frozenset : allows list, tuple, set, frozenset, deque, or generators and casts to a frozen set; see typing.FrozenSet below for sub-type constraints

deque : allows list, tuple, set, frozenset, deque, or generators and casts to a deque; see typing.Deque below for sub-type constraints

datetime.date : see Datetime Types below for more detail on parsing and validation

datetime.time : see Datetime Types below for more detail on parsing and validation

datetime.datetime : see Datetime Types below for more detail on parsing and validation

datetime.timedelta : see Datetime Types below for more detail on parsing and validation

typing.Any : allows any value including None, thus an Any field is optional

typing.Annotated : allows wrapping another type with arbitrary metadata, as per PEP-593. The Annotated hint may contain a single call to the Field function, but otherwise the additional metadata is ignored and the root type is used.

typing.TypeVar : constrains the values allowed based on constraints or bound, see TypeVar

typing.Union : see Unions below for more detail on parsing and validation

typing.Optional : Optional[x] is simply short hand for Union[x, None]; see Unions below for more detail on parsing and validation and Required Fields for details about required fields that can receive None as a value.

typing.List : see Typing Iterables below for more detail on parsing and validation

typing.Tuple : see Typing Iterables below for more detail on parsing and validation

subclass of typing.NamedTuple : Same as tuple but instantiates with the given namedtuple and validates fields since they are annotated. See Annotated Types below for more detail on parsing and validation

subclass of collections.namedtuple : Same as subclass of typing.NamedTuple but all fields will have type Any since they are not annotated

typing.Dict : see Typing Iterables below for more detail on parsing and validation

subclass of typing.TypedDict : Same as dict but pydantic will validate the dictionary since keys are annotated. See Annotated Types below for more detail on parsing and validation

typing.Set : see Typing Iterables below for more detail on parsing and validation

typing.FrozenSet : see Typing Iterables below for more detail on parsing and validation

typing.Deque : see Typing Iterables below for more detail on parsing and validation

typing.Sequence : see Typing Iterables below for more detail on parsing and validation

typing.Iterable : this is reserved for iterables that shouldn’t be consumed. See Infinite Generators below for more detail on parsing and validation

typing.Type : see Type below for more detail on parsing and validation

typing.Callable : see Callable below for more detail on parsing and validation

typing.Pattern : will cause the input value to be passed to re.compile(v) to create a regex pattern

ipaddress.IPv4Address : simply uses the type itself for validation by passing the value to IPv4Address(v); see Pydantic Types for other custom IP address types

ipaddress.IPv4Interface : simply uses the type itself for validation by passing the value to IPv4Address(v); see Pydantic Types for other custom IP address types

ipaddress.IPv4Network : simply uses the type itself for validation by passing the value to IPv4Network(v); see Pydantic Types for other custom IP address types

ipaddress.IPv6Address : simply uses the type itself for validation by passing the value to IPv6Address(v); see Pydantic Types for other custom IP address types

ipaddress.IPv6Interface : simply uses the type itself for validation by passing the value to IPv6Interface(v); see Pydantic Types for other custom IP address types

ipaddress.IPv6Network : simply uses the type itself for validation by passing the value to IPv6Network(v); see Pydantic Types for other custom IP address types

enum.Enum : checks that the value is a valid Enum instance

subclass of enum.Enum : checks that the value is a valid member of the enum; see Enums and Choices for more details

enum.IntEnum : checks that the value is a valid IntEnum instance

subclass of enum.IntEnum : checks that the value is a valid member of the integer enum; see Enums and Choices for more details

decimal.Decimal : pydantic attempts to convert the value to a string, then passes the string to Decimal(v)

pathlib.Path : simply uses the type itself for validation by passing the value to Path(v); see Pydantic Types for other more strict path types

uuid.UUID : strings and bytes (converted to strings) are passed to UUID(v), with a fallback to UUID(bytes=v) for bytes and bytearray; see Pydantic Types for other stricter UUID types

ByteSize : converts a bytes string with units to bytes

Typing Iterables

pydantic uses standard library typing types as defined in PEP 484 to define complex objects.

Infinite Generators

If you have a generator you can use Sequence as described above. In that case, the generator will be consumed and stored on the model as a list and its values will be validated with the sub-type of Sequence (e.g. int in Sequence[int]).

But if you have a generator that you don’t want to be consumed, e.g. an infinite generator or a remote data loader, you can define its type with Iterable:

Validating the first value

You can create a validator to validate the first value in an infinite generator and still not consume it entirely.

Unions

The Union type allows a model attribute to accept different types, e.g.:

However, as can be seen above, pydantic will attempt to ‘match’ any of the types defined under Union and will use the first one that matches. In the above example the id of user_03 was defined as a uuid.UUID class (which is defined under the attribute’s Union annotation) but as the uuid.UUID can be marshalled into an int it chose to match against the int type and disregarded the other types.

As such, it is recommended that, when defining Union annotations, the most specific type is included first and followed by less specific types.

In the above example, the UUID class should precede the int and str classes to preclude the unexpected representation as such:

Discriminated Unions (a.k.a. Tagged Unions)

When Union is used with multiple submodels, you sometimes know exactly which submodel needs to be checked and validated and want to enforce this. To do that you can set the same field - let’s call it my_discriminator - in each of the submodels with a discriminated value, which is one (or many) Literal value(s). For your Union, you can set the discriminator in its value: Field(discriminator='my_discriminator').

Setting a discriminated union has many benefits:

  • validation is faster since it is only attempted against one model
  • only one explicit error is raised in case of failure
  • the generated JSON schema implements the associated OpenAPI specification

Nested Discriminated Unions

Only one discriminator can be set for a field but sometimes you want to combine multiple discriminators. In this case you can always create “intermediate” models with __root__ and add your discriminator.

Enums and Choices

pydantic uses Python’s standard enum classes to define choices.

Datetime Types

Pydantic supports the following datetime types:

  • datetime fields can be:

    • datetime, existing datetime object

    • int or float, assumed as Unix time, i.e. seconds (if >= -2e10 or <= 2e10) or milliseconds (if < -2e10or > 2e10) since 1 January 1970

    • str, following formats work:

      • YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]
      • int or float as a string (assumed as Unix time)
  • date fields can be:

    • date, existing date object

    • int or float, see datetime

    • str, following formats work:

      • YYYY-MM-DD
      • int or float, see datetime
  • time fields can be:

    • time, existing time object

    • str, following formats work:

      • HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]
  • timedelta fields can be:

    • timedelta, existing timedelta object

    • int or float, assumed as seconds

    • str, following formats work:

      • -[HH:MM]SS[.ffffff]
      • [±]P[DD]DT[HH]H[MM]M[SS]S (ISO 8601 format for timedelta)

Booleans

A standard bool field will raise a ValidationError if the value is not one of the following:

  • A valid boolean (i.e. True or False),
  • The integers 0 or 1,
  • a str which when converted to lower case is one of '0', 'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes'
  • a bytes which is valid (per the previous rule) when decoded to str

Here is a script demonstrating some of these behaviors:

Callable

Fields can also be of type Callable:

Type

pydantic supports the use of Type[T] to specify that a field may only accept classes (not instances) that are subclasses of T.

You may also use Type to specify that any class is allowed.

TypeVar

TypeVar is supported either unconstrained, constrained or with a bound.

Literal Type

pydantic supports the use of typing.Literal (or typing_extensions.Literal prior to Python 3.8) as a lightweight way to specify that a field may accept only specific literal values:

One benefit of this field type is that it can be used to check for equality with one or more specific values without needing to declare custom validators:

With proper ordering in an annotated Union, you can use this to parse types of decreasing specificity:

Annotated Types

NamedTuple

TypedDict

Pydantic Types

pydantic also provides a variety of other useful types:

FilePath : like Path, but the path must exist and be a file

DirectoryPath : like Path, but the path must exist and be a directory

PastDate : like date, but the date should be in the past

FutureDate : like date, but the date should be in the future

EmailStr : requires email-validator to be installed; the input string must be a valid email address, and the output is a simple string

NameEmail : requires email-validator to be installed; the input string must be either a valid email address or in the format Fred Bloggs <[email protected]>, and the output is a NameEmail object which has two properties: name and email. For Fred Bloggs <[email protected]> the name would be "Fred Bloggs"; for [email protected] it would be "fred.bloggs".

PyObject : expects a string and loads the Python object importable at that dotted path; e.g. if 'math.cos' was provided, the resulting field value would be the function cos

Color : for parsing HTML and CSS colors; see Color Type

Json : a special type wrapper which loads JSON before parsing; see JSON Type

PaymentCardNumber : for parsing and validating payment cards; see payment cards

AnyUrl : any URL; see URLs

AnyHttpUrl : an HTTP URL; see URLs

HttpUrl : a stricter HTTP URL; see URLs

FileUrl : a file path URL; see URLs

PostgresDsn : a postgres DSN style URL; see URLs

CockroachDsn : a cockroachdb DSN style URL; see URLs

AmqpDsn : an AMQP DSN style URL as used by RabbitMQ, StormMQ, ActiveMQ etc.; see URLs

RedisDsn : a redis DSN style URL; see URLs

MongoDsn : a MongoDB DSN style URL; see URLs

KafkaDsn : a kafka DSN style URL; see URLs

stricturl : a type method for arbitrary URL constraints; see URLs

UUID1 : requires a valid UUID of type 1; see UUID above

UUID3 : requires a valid UUID of type 3; see UUID above

UUID4 : requires a valid UUID of type 4; see UUID above

UUID5 : requires a valid UUID of type 5; see UUID above

SecretBytes : bytes where the value is kept partially secret; see Secrets

SecretStr : string where the value is kept partially secret; see Secrets

IPvAnyAddress : allows either an IPv4Address or an IPv6Address

IPvAnyInterface : allows either an IPv4Interface or an IPv6Interface

IPvAnyNetwork : allows either an IPv4Network or an IPv6Network

NegativeFloat : allows a float which is negative; uses standard float parsing then checks the value is less than 0; see Constrained Types

NegativeInt : allows an int which is negative; uses standard int parsing then checks the value is less than 0; see Constrained Types

PositiveFloat : allows a float which is positive; uses standard float parsing then checks the value is greater than 0; see Constrained Types

PositiveInt : allows an int which is positive; uses standard int parsing then checks the value is greater than 0; see Constrained Types

conbytes : type method for constraining bytes; see Constrained Types

condecimal : type method for constraining Decimals; see Constrained Types

confloat : type method for constraining floats; see Constrained Types

conint : type method for constraining ints; see Constrained Types

condate : type method for constraining dates; see Constrained Types

conlist : type method for constraining lists; see Constrained Types

conset : type method for constraining sets; see Constrained Types

confrozenset : type method for constraining frozen sets; see Constrained Types

constr : type method for constraining strs; see Constrained Types

URLs

For URI/URL validation the following types are available:

  • AnyUrl: any scheme allowed, TLD not required, host required
  • AnyHttpUrl: scheme http or https, TLD not required, host required
  • HttpUrl: scheme http or https, TLD required, host required, max length 2083
  • FileUrl: scheme file, host not required
  • PostgresDsn: user info required, TLD not required, host required, as of V.10 PostgresDsn supports multiple hosts. The following schemes are supported:
    • postgres
    • postgresql
    • postgresql+asyncpg
    • postgresql+pg8000
    • postgresql+psycopg
    • postgresql+psycopg2
    • postgresql+psycopg2cffi
    • postgresql+py-postgresql
    • postgresql+pygresql
  • CockroachDsn: scheme cockroachdb, user info required, TLD not required, host required. Also, its supported DBAPI dialects:
    • cockroachdb+asyncpg
    • cockroachdb+psycopg2
  • AmqpDsn: schema amqp or amqps, user info not required, TLD not required, host not required
  • RedisDsn: scheme redis or rediss, user info not required, tld not required, host not required (CHANGED: user info) (e.g., rediss://:pass@localhost)
  • MongoDsn : scheme mongodb, user info not required, database name not required, port not required from v1.6 onwards), user info may be passed without user part (e.g., mongodb://mongodb0.example.com:27017)
  • stricturl: method with the following keyword arguments:
    • strip_whitespace: bool = True
    • min_length: int = 1
    • max_length: int = 2 ** 16
    • tld_required: bool = True
    • host_required: bool = True
    • allowed_schemes: Optional[Set[str]] = None

The above types (which all inherit from AnyUrl) will attempt to give descriptive errors when invalid URLs are provided:

If you require a custom URI/URL type, it can be created in a similar way to the types defined above.

URL Properties

Assuming an input URL of http://samuel:[email protected]:8000/the/path/?query=here#fragment=is;this=bit, the above types export the following properties:

  • scheme: always set - the url scheme (http above)

  • host: always set - the url host (example.com above)

  • host_type: always set - describes the type of host, either:

    • domain: e.g. example.com,
    • int_domain: international domain, see below, e.g. exampl£e.org,
    • ipv4: an IP V4 address, e.g. 127.0.0.1, or
    • ipv6: an IP V6 address, e.g. 2001:db8:ff00:42
  • user: optional - the username if included (samuel above)

  • password: optional - the password if included (pass above)

  • tld: optional - the top level domain (com above), Note: this will be wrong for any two-level domain, e.g. “co.uk”. You’ll need to implement your own list of TLDs if you require full TLD validation

  • port: optional - the port (8000 above)

  • path: optional - the path (/the/path/ above)

  • query: optional - the URL query (aka GET arguments or “search string”) (query=here above)

  • fragment: optional - the fragment (fragment=is;this=bit above)

If further validation is required, these properties can be used by validators to enforce specific behaviour:

International Domains

“International domains” (e.g. a URL where the host or TLD includes non-ascii characters) will be encoded via punycode (see this article for a good description of why this is important):

Color Type

You can use the Color data type for storing colors as per CSS3 specification. Colors can be defined via:

  • name (e.g. "Black", "azure")
  • hexadecimal value (e.g. "0x000", "#FFFFFF", "7fffd4")
  • RGB/RGBA tuples (e.g. (255, 255, 255), (255, 255, 255, 0.5))
  • RGB/RGBA strings (e.g. "rgb(255, 255, 255)", "rgba(255, 255, 255, 0.5)")
  • HSL strings (e.g. "hsl(270, 60%, 70%)", "hsl(270, 60%, 70%, .5)")

Color has the following methods:

original : the original string or tuple passed to Color

as_named : returns a named CSS3 color; fails if the alpha channel is set or no such color exists unless fallback=True is supplied, in which case it falls back to as_hex

as_hex : returns a string in the format #fff or #ffffff; will contain 4 (or 8) hex values if the alpha channel is set, e.g. #7f33cc26

as_rgb : returns a string in the format rgb(<red>, <green>, <blue>), or rgba(<red>, <green>, <blue>, <alpha>) if the alpha channel is set

as_rgb_tuple : returns a 3- or 4-tuple in RGB(a) format. The alpha keyword argument can be used to define whether the alpha channel should be included; options: True - always include, False - never include, None (default) - include if set

as_hsl : string in the format hsl(<hue deg>, <saturation %>, <lightness %>) or hsl(<hue deg>, <saturation %>, <lightness %>, <alpha>) if the alpha channel is set

as_hsl_tuple : returns a 3- or 4-tuple in HSL(a) format. The alpha keyword argument can be used to define whether the alpha channel should be included; options: True - always include, False - never include, None (the default) - include if set

The __str__ method for Color returns self.as_named(fallback=True).

Secret Types

You can use the SecretStr and the SecretBytes data types for storing sensitive information that you do not want to be visible in logging or tracebacks. SecretStr and SecretBytes can be initialized idempotently or by using str or bytes literals respectively. The SecretStr and SecretBytes will be formatted as either '**********' or '' on conversion to json.

Json Type

You can use Json data type to make pydantic first load a raw JSON string. It can also optionally be used to parse the loaded object into another type base on the type Json is parameterised with:

Payment Card Numbers

The PaymentCardNumber type validates payment cards (such as a debit or credit card).

PaymentCardBrand can be one of the following based on the BIN:

  • PaymentCardBrand.amex
  • PaymentCardBrand.mastercard
  • PaymentCardBrand.visa
  • PaymentCardBrand.other

The actual validation verifies the card number is:

  • a str of only digits
  • luhn valid
  • the correct length based on the BIN, if Amex, Mastercard or Visa, and between 12 and 19 digits for all other brands

Constrained Types

The value of numerous common types can be restricted using con* type functions:

Where Field refers to the field function.

Arguments to conlist

The following arguments are available when using the conlist type function

  • item_type: Type[T]: type of the list items
  • min_items: int = None: minimum number of items in the list
  • max_items: int = None: maximum number of items in the list
  • unique_items: bool = None: enforces list elements to be unique

Arguments to conset

The following arguments are available when using the conset type function

  • item_type: Type[T]: type of the set items
  • min_items: int = None: minimum number of items in the set
  • max_items: int = None: maximum number of items in the set

Arguments to confrozenset

The following arguments are available when using the confrozenset type function

  • item_type: Type[T]: type of the frozenset items
  • min_items: int = None: minimum number of items in the frozenset
  • max_items: int = None: maximum number of items in the frozenset

Arguments to conint

The following arguments are available when using the conint type function

  • strict: bool = False: controls type coercion
  • gt: int = None: enforces integer to be greater than the set value
  • ge: int = None: enforces integer to be greater than or equal to the set value
  • lt: int = None: enforces integer to be less than the set value
  • le: int = None: enforces integer to be less than or equal to the set value
  • multiple_of: int = None: enforces integer to be a multiple of the set value

Arguments to confloat

The following arguments are available when using the confloat type function

  • strict: bool = False: controls type coercion
  • gt: float = None: enforces float to be greater than the set value
  • ge: float = None: enforces float to be greater than or equal to the set value
  • lt: float = None: enforces float to be less than the set value
  • le: float = None: enforces float to be less than or equal to the set value
  • multiple_of: float = None: enforces float to be a multiple of the set value
  • allow_inf_nan: bool = True: whether to allows infinity (+inf an -inf) and NaN values, defaults to True, set to False for compatibility with JSON, see #3994 for more details, added in V1.10

Arguments to condecimal

The following arguments are available when using the condecimal type function

  • gt: Decimal = None: enforces decimal to be greater than the set value
  • ge: Decimal = None: enforces decimal to be greater than or equal to the set value
  • lt: Decimal = None: enforces decimal to be less than the set value
  • le: Decimal = None: enforces decimal to be less than or equal to the set value
  • max_digits: int = None: maximum number of digits within the decimal. it does not include a zero before the decimal point or trailing decimal zeroes
  • decimal_places: int = None: max number of decimal places allowed. it does not include trailing decimal zeroes
  • multiple_of: Decimal = None: enforces decimal to be a multiple of the set value

Arguments to constr

The following arguments are available when using the constr type function

  • strip_whitespace: bool = False: removes leading and trailing whitespace
  • to_upper: bool = False: turns all characters to uppercase
  • to_lower: bool = False: turns all characters to lowercase
  • strict: bool = False: controls type coercion
  • min_length: int = None: minimum length of the string
  • max_length: int = None: maximum length of the string
  • curtail_length: int = None: shrinks the string length to the set value when it is longer than the set value
  • regex: str = None: regex to validate the string against

Arguments to conbytes

The following arguments are available when using the conbytes type function

  • strip_whitespace: bool = False: removes leading and trailing whitespace
  • to_upper: bool = False: turns all characters to uppercase
  • to_lower: bool = False: turns all characters to lowercase
  • min_length: int = None: minimum length of the byte string
  • max_length: int = None: maximum length of the byte string
  • strict: bool = False: controls type coercion

Arguments to condate

The following arguments are available when using the condate type function

  • gt: date = None: enforces date to be greater than the set value
  • ge: date = None: enforces date to be greater than or equal to the set value
  • lt: date = None: enforces date to be less than the set value
  • le: date = None: enforces date to be less than or equal to the set value

Strict Types

You can use the StrictStr, StrictBytes, StrictInt, StrictFloat, and StrictBool types to prevent coercion from compatible types. These types will only pass validation when the validated value is of the respective type or is a subtype of that type. This behavior is also exposed via the strict field of the ConstrainedStr, ConstrainedBytes, ConstrainedFloat and ConstrainedInt classes and can be combined with a multitude of complex validation rules.

The following caveats apply:

  • StrictBytes (and the strict option of ConstrainedBytes) will accept both bytes, and bytearray types.
  • StrictInt (and the strict option of ConstrainedInt) will not accept bool types, even though bool is a subclass of int in Python. Other subclasses will work.
  • StrictFloat (and the strict option of ConstrainedFloat) will not accept int.

ByteSize

You can use the ByteSize data type to convert byte string representation to raw bytes and print out human readable versions of the bytes as well.

Custom Data Types

You can also define your own custom data types. There are several ways to achieve it.

Classes with __get_validators__

You use a custom class with a classmethod __get_validators__. It will be called to get validators to parse and validate the input data.

Similar validation could be achieved using constr(regex=...) except the value won’t be formatted with a space, the schema would just include the full pattern and the returned value would be a vanilla string.

See schema for more details on how the model’s schema is generated.

Arbitrary Types Allowed

You can allow arbitrary types using the arbitrary_types_allowed config in the Model Config.

Generic Classes as Types

You can use Generic Classes as field types and perform custom validation based on the “type parameters” (or sub-types) with __get_validators__.

If the Generic class that you are using as a sub-type has a classmethod __get_validators__ you don’t need to use arbitrary_types_allowed for it to work.

Because you can declare validators that receive the current field, you can extract the sub_fields (from the generic class type parameters) and validate data with them.