* Remove Cython * fix CI * fix coverage * fix tests * switching to pypyroject.toml * pre-commit all and use pre-commit for linting * no mypy tests on macos and windows on ci, use flake8-pyproject * fix docs and tests CI * check build is working * drop pytest-cov * window and macos ci with 3.11, reduce filtering * use pip-tools to pin all dependencies * fix docs and fastapi tests * fix test deps for 3.7 * no cache on tests job * revert fastapi changes, fix coverage * fix mypy coverage * test with older mypy * dotenv not required for mypy tests * split testing requirements std and extra * typo * @PrettyWood comments * correct branch name * mypy python_version and pr template
37 KiB
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)orLiteral[None](equivalent according to PEP 484)- allows only
Nonevalue 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 anint; 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,
intfloatandDecimalare coerced usingstr(v),bytesandbytearrayare converted usingv.decode(), enums inheriting fromstrare converted usingv.value, and all other types cause an error bytesbytesare accepted as-is,bytearrayis converted usingbytes(v),strare converted usingv.encode(), andint,float, andDecimalare coerced usingstr(v).encode()list- allows
list,tuple,set,frozenset,deque, or generators and casts to a list; seetyping.Listbelow for sub-type constraints tuple- allows
list,tuple,set,frozenset,deque, or generators and casts to a tuple; seetyping.Tuplebelow for sub-type constraints dictdict(v)is used to attempt to convert a dictionary; seetyping.Dictbelow for sub-type constraintsset- allows
list,tuple,set,frozenset,deque, or generators and casts to a set; seetyping.Setbelow for sub-type constraints frozenset- allows
list,tuple,set,frozenset,deque, or generators and casts to a frozen set; seetyping.FrozenSetbelow for sub-type constraints deque- allows
list,tuple,set,frozenset,deque, or generators and casts to a deque; seetyping.Dequebelow 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 anAnyfield is optional typing.Annotated- allows wrapping another type with arbitrary metadata, as per PEP-593. The
Annotatedhint may contain a single call to theFieldfunction, but otherwise the additional metadata is ignored and the root type is used. typing.TypeVar- constrains the values allowed based on
constraintsorbound, see TypeVar typing.Union- see Unions below for more detail on parsing and validation
typing.OptionalOptional[x]is simply short hand forUnion[x, None]; see Unions below for more detail on parsing and validation and Required Fields for details about required fields that can receiveNoneas 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
tuplebut 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.NamedTuplebut all fields will have typeAnysince they are not annotated typing.Dict- see Typing Iterables below for more detail on parsing and validation
subclass of typing.TypedDict- Same as
dictbut 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 toUUID(bytes=v)forbytesandbytearray; 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.
{!.tmp_examples/types_iterables.md!}
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:
{!.tmp_examples/types_infinite_generator.md!}
!!! warning
Iterable fields only perform a simple check that the argument is iterable and
won't be consumed.
No validation of their values is performed as it cannot be done without consuming
the iterable.
!!! tip If you want to validate the values of an infinite generator you can create a separate model and use it while consuming the generator, reporting the validation errors as appropriate.
pydantic can't validate the values automatically for you because it would require
consuming the infinite generator.
Validating the first value
You can create a validator to validate the first value in an infinite generator and still not consume it entirely.
{!.tmp_examples/types_infinite_generator_validate_first.md!}
Unions
The Union type allows a model attribute to accept different types, e.g.:
!!! info
You may get unexpected coercion with Union; see below.
Know that you can also make the check slower but stricter by using Smart Union
{!.tmp_examples/types_union_incorrect.md!}
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.
!!! warning
typing.Union also ignores order when defined,
so Union[int, float] == Union[float, int] which can lead to unexpected behaviour
when combined with matching based on the Union type order inside other type definitions, such as List and Dict
types (because Python treats these definitions as singletons).
For example, Dict[str, Union[int, float]] == Dict[str, Union[float, int]] with the order based on the first time it was defined.
Please note that this can also be affected by third party libraries
and their internal type definitions and the import orders.
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:
{!.tmp_examples/types_union_correct.md!}
!!! tip
The type Optional[x] is a shorthand for Union[x, None].
`Optional[x]` can also be used to specify a required field that can take `None` as a value.
See more details in [Required Fields](models.md#required-fields).
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
{!.tmp_examples/types_union_discriminated.md!}
!!! note
Using the Annotated Fields syntax can be handy to regroup
the Union and discriminator information. See below for an example!
!!! warning
Discriminated unions cannot be used with only a single variant, such as Union[Cat].
Python changes `Union[T]` into `T` at interpretation time, so it is not possible for `pydantic` to
distinguish fields of `Union[T]` from `T`.
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.
{!.tmp_examples/types_union_discriminated_nested.md!}
Enums and Choices
pydantic uses Python's standard enum classes to define choices.
{!.tmp_examples/types_choices.md!}
Datetime Types
Pydantic supports the following datetime types:
-
datetimefields can be:-
datetime, existingdatetimeobject -
intorfloat, assumed as Unix time, i.e. seconds (if >=-2e10or <=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]]]intorfloatas a string (assumed as Unix time)
-
-
datefields can be:-
date, existingdateobject -
intorfloat, seedatetime -
str, following formats work:YYYY-MM-DDintorfloat, seedatetime
-
-
timefields can be:-
time, existingtimeobject -
str, following formats work:HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]]]
-
-
timedeltafields can be:-
timedelta, existingtimedeltaobject -
intorfloat, assumed as seconds -
str, following formats work:[-][DD ][HH:MM]SS[.ffffff][±]P[DD]DT[HH]H[MM]M[SS]S(ISO 8601 format for timedelta)
-
{!.tmp_examples/types_dt.md!}
Booleans
!!! warning
The logic for parsing bool fields has changed as of version v1.0.
Prior to **v1.0**, `bool` parsing never failed, leading to some unexpected results.
The new logic is described below.
A standard bool field will raise a ValidationError if the value is not one of the following:
- A valid boolean (i.e.
TrueorFalse), - The integers
0or1, - a
strwhich when converted to lower case is one of'0', 'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes' - a
byteswhich is valid (per the previous rule) when decoded tostr
!!! note
If you want stricter boolean logic (e.g. a field which only permits True and False) you can
use StrictBool.
Here is a script demonstrating some of these behaviors:
{!.tmp_examples/types_boolean.md!}
Callable
Fields can also be of type Callable:
{!.tmp_examples/types_callable.md!}
!!! warning Callable fields only perform a simple check that the argument is callable; no validation of arguments, their types, or the return type is performed.
Type
pydantic supports the use of Type[T] to specify that a field may only accept classes (not instances)
that are subclasses of T.
{!.tmp_examples/types_type.md!}
You may also use Type to specify that any class is allowed.
{!.tmp_examples/types_bare_type.md!}
TypeVar
TypeVar is supported either unconstrained, constrained or with a bound.
{!.tmp_examples/types_typevar.md!}
Literal Type
!!! note This is a new feature of the Python standard library as of Python 3.8; prior to Python 3.8, it requires the typing-extensions package.
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:
{!.tmp_examples/types_literal1.md!}
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:
{!.tmp_examples/types_literal2.md!}
With proper ordering in an annotated Union, you can use this to parse types of decreasing specificity:
{!.tmp_examples/types_literal3.md!}
Annotated Types
NamedTuple
{!.tmp_examples/annotated_types_named_tuple.md!}
TypedDict
!!! note This is a new feature of the Python standard library as of Python 3.8. Prior to Python 3.8, it requires the typing-extensions package. But required and optional fields are properly differentiated only since Python 3.9. We therefore recommend using typing-extensions with Python 3.8 as well.
{!.tmp_examples/annotated_types_typed_dict.md!}
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 <fred.bloggs@example.com>, and the output is aNameEmailobject which has two properties:nameandemail. ForFred Bloggs <fred.bloggs@example.com>the name would be"Fred Bloggs"; forfred.bloggs@example.comit 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 functioncos 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
RabbitMqDsn- an
AMQPDSN 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
UUIDabove UUID3- requires a valid UUID of type 3; see
UUIDabove UUID4- requires a valid UUID of type 4; see
UUIDabove UUID5- requires a valid UUID of type 5; see
UUIDabove 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
IPv4Addressor anIPv6Address IPvAnyInterface- allows either an
IPv4Interfaceor anIPv6Interface IPvAnyNetwork- allows either an
IPv4Networkor anIPv6Network NegativeFloat- allows a float which is negative; uses standard
floatparsing then checks the value is less than 0; see Constrained Types NegativeInt- allows an int which is negative; uses standard
intparsing then checks the value is less than 0; see Constrained Types PositiveFloat- allows a float which is positive; uses standard
floatparsing then checks the value is greater than 0; see Constrained Types PositiveInt- allows an int which is positive; uses standard
intparsing 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 requiredAnyHttpUrl: schemehttporhttps, TLD not required, host requiredHttpUrl: schemehttporhttps, TLD required, host required, max length 2083FileUrl: schemefile, host not requiredPostgresDsn: user info required, TLD not required, host required, as of V.10PostgresDsnsupports multiple hosts. The following schemes are supported:postgrespostgresqlpostgresql+asyncpgpostgresql+pg8000postgresql+psycopg2postgresql+psycopg2cffipostgresql+py-postgresqlpostgresql+pygresql
CockroachDsn: schemecockroachdb, user info required, TLD not required, host required. Also, its supported DBAPI dialects:cockroachdb+asyncpgcockroachdb+psycopg2
AmqpDsn: schemaamqporamqps, user info not required, TLD not required, host not requiredRedisDsn: schemeredisorrediss, user info not required, tld not required, host not required (CHANGED: user infoMongoDsn: schememongodb, 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.,rediss://:pass@localhost)stricturl: method with the following keyword arguments:strip_whitespace: bool = Truemin_length: int = 1max_length: int = 2 ** 16tld_required: bool = Truehost_required: bool = Trueallowed_schemes: Optional[Set[str]] = None
!!! warning
In V1.10.0 and v1.10.1 stricturl also took an optional quote_plus argument and URL components were percent
encoded in some cases. This feature was removed in v1.10.2, see
#4470 for explanation and more details.
The above types (which all inherit from AnyUrl) will attempt to give descriptive errors when invalid URLs are
provided:
{!.tmp_examples/types_urls.md!}
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:pass@example.com:8000/the/path/?query=here#fragment=is;this=bit,
the above types export the following properties:
-
scheme: always set - the url scheme (httpabove) -
host: always set - the url host (example.comabove) -
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, oripv6: an IP V6 address, e.g.2001:db8:ff00:42
-
user: optional - the username if included (samuelabove) -
password: optional - the password if included (passabove) -
tld: optional - the top level domain (comabove), 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 (8000above) -
path: optional - the path (/the/path/above) -
query: optional - the URL query (aka GET arguments or "search string") (query=hereabove) -
fragment: optional - the fragment (fragment=is;this=bitabove)
If further validation is required, these properties can be used by validators to enforce specific behaviour:
{!.tmp_examples/types_url_properties.md!}
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):
{!.tmp_examples/types_url_punycode.md!}
!!! warning #### Underscores in Hostnames
In *pydantic* underscores are allowed in all parts of a domain except the tld.
Technically this might be wrong - in theory the hostname cannot have underscores, but subdomains can.
To explain this; consider the following two cases:
- `exam_ple.co.uk`: the hostname is `exam_ple`, which should not be allowed since it contains an underscore
- `foo_bar.example.com` the hostname is `example`, which should be allowed since the underscore is in the subdomain
Without having an exhaustive list of TLDs, it would be impossible to differentiate between these two. Therefore
underscores are allowed, but you can always do further validation in a validator if desired.
Also, Chrome, Firefox, and Safari all currently accept `http://exam_ple.com` as a URL, so we're in good
(or at least big) company.
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)")
{!.tmp_examples/types_color.md!}
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=Trueis supplied, in which case it falls back toas_hex as_hex- returns a string in the format
#fffor#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>), orrgba(<red>, <green>, <blue>, <alpha>)if the alpha channel is set as_rgb_tuple- returns a 3- or 4-tuple in RGB(a) format. The
alphakeyword 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 %>)orhsl(<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
alphakeyword 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).
!!! note
the as_hsl* refer to hue, saturation, lightness "HSL" as used in html and most of the world, not
"HLS" as used in Python's colorsys.
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.
{!.tmp_examples/types_secret_types.md!}
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:
{!.tmp_examples/types_json_type.md!}
Payment Card Numbers
The PaymentCardNumber type validates payment cards
(such as a debit or credit card).
{!.tmp_examples/types_payment_card_number.md!}
PaymentCardBrand can be one of the following based on the BIN:
PaymentCardBrand.amexPaymentCardBrand.mastercardPaymentCardBrand.visaPaymentCardBrand.other
The actual validation verifies the card number is:
- a
strof 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:
{!.tmp_examples/types_constrained.md!}
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 itemsmin_items: int = None: minimum number of items in the listmax_items: int = None: maximum number of items in the listunique_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 itemsmin_items: int = None: minimum number of items in the setmax_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 itemsmin_items: int = None: minimum number of items in the frozensetmax_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 coerciongt: int = None: enforces integer to be greater than the set valuege: int = None: enforces integer to be greater than or equal to the set valuelt: int = None: enforces integer to be less than the set valuele: int = None: enforces integer to be less than or equal to the set valuemultiple_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 coerciongt: float = None: enforces float to be greater than the set valuege: float = None: enforces float to be greater than or equal to the set valuelt: float = None: enforces float to be less than the set valuele: float = None: enforces float to be less than or equal to the set valuemultiple_of: float = None: enforces float to be a multiple of the set valueallow_inf_nan: bool = True: whether to allows infinity (+infan-inf) and NaN values, defaults toTrue, set toFalsefor compatibility withJSON, 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 valuege: Decimal = None: enforces decimal to be greater than or equal to the set valuelt: Decimal = None: enforces decimal to be less than the set valuele: Decimal = None: enforces decimal to be less than or equal to the set valuemax_digits: int = None: maximum number of digits within the decimal. it does not include a zero before the decimal point or trailing decimal zeroesdecimal_places: int = None: max number of decimal places allowed. it does not include trailing decimal zeroesmultiple_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 whitespaceto_upper: bool = False: turns all characters to uppercaseto_lower: bool = False: turns all characters to lowercasestrict: bool = False: controls type coercionmin_length: int = None: minimum length of the stringmax_length: int = None: maximum length of the stringcurtail_length: int = None: shrinks the string length to the set value when it is longer than the set valueregex: 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 whitespaceto_upper: bool = False: turns all characters to uppercaseto_lower: bool = False: turns all characters to lowercasemin_length: int = None: minimum length of the byte stringmax_length: int = None: maximum length of the byte stringstrict: 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 valuege: date = None: enforces date to be greater than or equal to the set valuelt: date = None: enforces date to be less than the set valuele: 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 thestrictoption ofConstrainedBytes) will accept bothbytes, andbytearraytypes.StrictInt(and thestrictoption ofConstrainedInt) will not acceptbooltypes, even thoughboolis a subclass ofintin Python. Other subclasses will work.StrictFloat(and thestrictoption ofConstrainedFloat) will not acceptint.
{!.tmp_examples/types_strict.md!}
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.
!!! info
Note that 1b will be parsed as "1 byte" and not "1 bit".
{!.tmp_examples/types_bytesize.md!}
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.
!!! tip
These validators have the same semantics as in Validators, you can
declare a parameter config, field, etc.
{!.tmp_examples/types_custom_type.md!}
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.
{!.tmp_examples/types_arbitrary_allowed.md!}
Generic Classes as Types
!!! warning This is an advanced technique that you might not need in the beginning. In most of the cases you will probably be fine with standard pydantic models.
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.
{!.tmp_examples/types_generics.md!}