* moving docs to mkdocs * transfering readme to md and more * fixing build * splitting usage.md * improving schema.md and index.md * fix make_history.rst * models intro * working on data conversation and required fields * more fixes to models.md * list all standard types supported * list of pydantic types * tweaks * update links in code * Apply suggestions from code review incorporate @dmontagu's suggestions. Co-Authored-By: dmontagu <35119617+dmontagu@users.noreply.github.com> * Apply suggestions from code review more missed suggestions. Co-Authored-By: dmontagu <35119617+dmontagu@users.noreply.github.com> * Apply suggestions from code review more corrects. * cleanup * Field order warning * fix and regenerate benchmarks * format examples better, cleanup * improve schema mapping table * correct highlighting file types in schema.md * add redirects in javascript * add logo
22 KiB
Where possible pydantic uses standard library types to define fields thus smoothing the learning curve. For some types however no standard library type exists, here pydantic implements many commonly used types. If no existing type exists for your purpose you can also implement your own 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 (eg. require a positive int) see Constrained Types.
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, therefore strings and floats will be coerced to ints, 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-as,
intfloatandDecimalare coerced usingstr(v),bytesandbytearrayare converted usingv.decode(), enums inheriting fromstrare converted usingv.value, all other types cause an error bytesbytesare accepted as-as,bytearrayis converted usingbytes(v),strare converted usingv.encode(),intfloatandDecimalare coerced usingstr(v).encode()list- allows
list,tuple,set,frozensetor generators and casts to a list, seetyping.Listbelow for sub-type constraints tuple- allows
list,tuple,set,frozensetor 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,frozensetor generators and casts to a set, seetyping.Setbelow for sub-type constraints frozonset- allows
list,tuple,set,frozensetor generators and casts to a frozen set, seetyping.FrozenSetbelow 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.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 validationtyping.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
typing.Dict- see Typing Iterables 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.Sequence- see Typing Iterables 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 member of the enum, see Enums and Choices for more details
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 allowed passed to
UUID(v), see Pydantic Types for other more strict UUID types
Typing Iterables
pydantic uses standard library typing types as defined in PEP 484 to define complex objects.
{!./examples/ex_typing.py!}
(This script is complete, it should run "as is")
Unions
The Union type allows a model attribute to accept different types, e.g.:
!!! warning This script is complete, it should run but may be is wrong, see below.
{!./examples/union_type_incorrect.py!}
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 that the most specific type is defined 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:
{!./examples/union_type_correct.py!}
(This script is complete, it should run "as is")
Enums and Choices
pydantic uses python's standard enum classes to define choices.
{!./examples/choices.py!}
(This script is complete, it should run "as is")
Datetime Types
Pydantic supports the following datetime types:
-
datetimefields can be:-
datetime, existingdatetimeobject -
intorfloat, assumed as Unix time, e.g. seconds (if <=2e10) or milliseconds (if >2e10) since 1 January 1970 -
str, following formats work:YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z[±]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]]
-
-
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)
-
{!./examples/datetime_example.py!}
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'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes' - a
byteswhich is valid (per the previous rule) when decoded tostr
Here is a script demonstrating some of these behaviors:
{!./examples/boolean.py!}
(This script is complete, it should run "as is")
Callable
Fields can also be of type Callable:
{!./examples/callable.py!}
(This script is complete, it should run "as is")
!!! 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.
{!./examples/type_type.py!}
You may also use Type to specify that any class is allowed.
{!./examples/bare_type_type.py!}
Literal Type
!!! note This is not strictly part of the python standard library, instead the typing-extensions package is required.
pydantic supports the use of typing_extensions.Literal as a lightweight way to specify that a field
may accept only specific literal values:
{!./examples/literal1.py!}
(This script is complete, it should run "as is")
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:
{!./examples/literal2.py!}
(This script is complete, it should run "as is")
With proper ordering in an annotated Union, you can use this to parse types of decreasing specificity:
{!./examples/literal3.py!}
(This script is complete, it should run "as is")
Pydantic Types
pydantic comes with the following types:
FilePath- like
Pathbut the path must exist and be a file DirectoryPath- like
Pathbut the path must exist and be a directory EmailStr- requires email-validator to be installed, requires the input string to be a valid email address, outputs a simple string
NameEmail- requires email-validator to be installed, requires the input
string to be a valid email address, outputs a
NameEmailobject which has two properties:nameandemail, also accepts emails in the formatFred Bloggs <fred.bloggs@example.com>in which case "Fred Bloggs" is used for name, if simplyfred.bloggs@example.comis provided, name would be "fred.bloggs" PyObject- expects a string and loads the python object at that dotted path, e.g. if
'math.cos'was provided the resulting field value would be the functioncos Color- for parsing HTML can CSS colors, see Color Type
Json- a special type wrapper which parses 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- stricter HTTP URL, see URLs
PostgresDsn- a postgres DSN style URL, see URLs
RedisDsn- a redis 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 a
IPv4Addressor aIPv6Address IPvAnyInterface- allows either a
IPv4Interfaceor aIPv6Interface IPvAnyNetwork- allows either a
IPv4Networkor aIPv6Network NegativeFloat- allows a float which is negative, uses standard
floatparsing, then checks the value is less than 0, see Constrained Types NegativeInt- allows a int which is negative, uses standard
intparsing, then checks the value is less than 0, see Constrained Types PositiveFloat- allows a float which is negative, uses standard
floatparsing, then checks the value is greater than 0, see Constrained Types PositiveInt- allows a int which is negative, 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
conlist- type method for constraining lists, 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 requiredAnyHttpUrl: schemahttporhttps, TLD not requiredHttpUrl: schemahttporhttps, TLD required, max length 2083PostgresDsn: schemapostgresorpostgresql, userinfo required, TLD not requiredRedisDsn: schemaredis, userinfo required, tld not requiredstricturl, method with the following keyword arguments:strip_whitespace: bool = Truemin_length: int = 1max_length: int = 2 ** 16tld_required: bool = Trueallowed_schemes: Optional[Set[str]] = None
If you require custom types they can be created in a similar way to the application specific types defined above.
The above types (which all inherit from AnyUrl) will attempt to give descriptive errors when invalid URLs are
provided:
{!./examples/urls.py!}
(This script is complete, it should run "as is")
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 schema e.g.httpabove -
host: always set - the url host e.g.example.comabove -
host_type: always set - describes the type of host, either:domain: e.g. forexample.com,int_domain: international domain, see below, e.g. forexampl£e.org,ipv4: an IP V4 address, e.g. for127.0.0.1, oripv6: an IP V6 address, e.g. for2001:db8:ff00:42
-
user: optional - the username if included e.g.samuelabove -
password: optional - the password if included e.g.passabove -
tld: optional - the top level domain e.g.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 e.g.8000above -
path: optional - the path e.g./the/path/above -
query: optional - the URL query (aka GET arguments or "search string") e.g.query=hereabove -
fragment: optional - the fragment e.g.fragment=is;this=bitabove
If further validation is required, these properties can be used by validators to enforce specific behaviour:
{!./examples/url_properties.py!}
(This script is complete, it should run "as is")
International Domains
"International domains" (e.g. a URL where the host includes non-ascii characters) will be encode via punycode (see this article for a good description of why this is important):
{!./examples/url_punycode.py!}
(This script is complete, it should run "as is")
Underscores in Hostnames
!!! note 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` hostname is `exam_ple`, should not be allowed as there's an underscore in there
- `foo_bar.example.com` hostname is `example` 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, you could do further validation in a validator if you wanted.
Also, chrome currently accepts `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. Color 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)"or"rgba(255, 255, 255, 0.5)") - HSL strings
(e.g.
"hsl(270, 60%, 70%)"or"hsl(270, 60%, 70%, .5)")
{!./examples/ex_color_type.py!}
(This script is complete, it should run "as is")
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 when it falls back toas_hex as_hex- string in the format
#ffffffor#fff, can also be a 4 or 8 hex values if the alpha channel is set, e.g.#7f33cc26 as_rgb- 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(the 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.
The SecretStr and SecretBytes will be formatted as either '**********' or '' on conversion to json.
{!./examples/ex_secret_types.py!}
(This script is complete, it should run "as is")
Json Type
You can use Json data type - Pydantic will first parse raw JSON string and then will validate parsed object
against defined Json structure if it's provided.
{!./examples/ex_json_type.py!}
(This script is complete, it should run "as is")
Payment Card Numbers
The PaymentCardNumber type validates payment cards
(such as a debit or credit card).
{!./examples/payment_card_number.py!}
(This script is complete, it should be run "as is")
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 methods:
{!./examples/constrained_types.py!}
(This script is complete, it should run "as is")
Strict Types
You can use the StrictStr, 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, ConstrainedFloat and
ConstrainedInt classes and can be combined with a multitude of complex validation rules.
The following caveats apply:
StrictInt(and thestrictoption ofConstrainedInt) will not acceptbooltypes, even thoughboolis a subclass ofintin Python. Other subclasses will work.StrictFloat(and thestrictoption ofConstrainedFloat) will not acceptint.
{!./examples/strict_types.py!}
(This script is complete, it should run "as is")
Custom Data Types
You can also define your own data types. The class method __get_validators__ will be called
to get validators to parse and validate the input data.
{!./examples/custom_data_types.py!}
(This script is complete, it should run "as is")