docs/index.md
{{ version }}.
Pydantic is the most widely used data validation library for Python.
Fast and extensible, Pydantic plays nicely with your linters/IDE/brain. Define how data should be in pure, canonical Python 3.9+; validate it with Pydantic.
Sign up for our newsletter, The Pydantic Stack, with updates & tutorials on Pydantic, Logfire, and Pydantic AI:
<form method="POST" action="https://eu.customerioforms.com/forms/submit_action?site_id=53d2086c3c4214eaecaa&form_id=14b22611745b458&success_url=https://docs.pydantic.dev/" class="md-typeset" style="display: flex; align-items: center; gap: 0.5rem; max-width: 100%;"> <input type="email" id="email_input" name="email" class="md-input md-input--stretch" style="flex: 1; background: var(--md-default-bg-color); color: var(--md-default-fg-color);" required placeholder="Email" data-1p-ignore data-lpignore="true" data-protonpass-ignore="true" data-bwignore="true" /> <input type="hidden" id="source_input" name="source" value="pydantic" /> <button type="submit" class="md-button md-button--primary">Subscribe</button> </form>dataclass and TypedDict. Learn more…Installing Pydantic is as simple as: pip install pydantic
To see Pydantic at work, let's start with a simple example, creating a custom class that inherits from BaseModel:
from datetime import datetime
from pydantic import BaseModel, PositiveInt
class User(BaseModel):
id: int # (1)!
name: str = 'John Doe' # (2)!
signup_ts: datetime | None # (3)!
tastes: dict[str, PositiveInt] # (4)!
external_data = {
'id': 123,
'signup_ts': '2019-06-01 12:22', # (5)!
'tastes': {
'wine': 9,
b'cheese': 7, # (6)!
'cabbage': '1', # (7)!
},
}
user = User(**external_data) # (8)!
print(user.id) # (9)!
#> 123
print(user.model_dump()) # (10)!
"""
{
'id': 123,
'name': 'John Doe',
'signup_ts': datetime.datetime(2019, 6, 1, 12, 22),
'tastes': {'wine': 9, 'cheese': 7, 'cabbage': 1},
}
"""
id is of type int; the annotation-only declaration tells Pydantic that this field is required. Strings,
bytes, or floats will be coerced to integers if possible; otherwise an exception will be raised.name is a string; because it has a default, it is not required.signup_ts is a [datetime][datetime.datetime] field that is required, but the value None may be provided;
Pydantic will process either a Unix timestamp integer (e.g. 1496498400)
or a string representing the date and time.tastes is a dictionary with string keys and positive integer values. The PositiveInt type is
shorthand for Annotated[int, annotated_types.Gt(0)].datetime][datetime.datetime] object.bytes, but Pydantic will take care of coercing it to a string.'1' to the integer 1.User by passing our external data to User as keyword arguments.model_dump()][pydantic.BaseModel.model_dump].If validation fails, Pydantic will raise an error with a breakdown of what was wrong:
# continuing the above example...
from datetime import datetime
from pydantic import BaseModel, PositiveInt, ValidationError
class User(BaseModel):
id: int
name: str = 'John Doe'
signup_ts: datetime | None
tastes: dict[str, PositiveInt]
external_data = {'id': 'not an int', 'tastes': {}} # (1)!
try:
User(**external_data) # (2)!
except ValidationError as e:
print(e.errors())
"""
[
{
'type': 'int_parsing',
'loc': ('id',),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'input': 'not an int',
'url': 'https://errors.pydantic.dev/2/v/int_parsing',
},
{
'type': 'missing',
'loc': ('signup_ts',),
'msg': 'Field required',
'input': {'id': 'not an int', 'tastes': {}},
'url': 'https://errors.pydantic.dev/2/v/missing',
},
]
"""
id is not a valid integer, and signup_ts is missing.User will raise a [ValidationError][pydantic_core.ValidationError] with a list of errors.Hundreds of organisations and packages are using Pydantic. Some of the prominent companies and organizations around the world who are using Pydantic include:
{{ organisations }}
For a more comprehensive list of open-source projects using Pydantic see the list of dependents on github, or you can find some awesome projects using Pydantic in awesome-pydantic.