Welcome to Pydantic - Pydantic (original) (raw)

CI Coverage
pypi CondaForge downloads
license llms.txt

Documentation for version: v2.11.4.

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.

Monitor Pydantic with Logfire 🔥

Built by the same team as Pydantic, Logfire is an application monitoring tool that is as simple to use and powerful as Pydantic itself.

Logfire integrates with many popular Python libraries including FastAPI, OpenAI and Pydantic itself, so you can use Logfire to monitor Pydantic validations and understand why some inputs fail validation:

Monitoring Pydantic with Logfire

`from datetime import datetime

import logfire

from pydantic import BaseModel

logfire.configure() logfire.instrument_pydantic() # (1)!

class Delivery(BaseModel): timestamp: datetime dimensions: tuple[int, int]

this will record details of a successful validation to logfire

m = Delivery(timestamp='2020-01-02T03:04:05Z', dimensions=['10', '20']) print(repr(m.timestamp)) #> datetime.datetime(2020, 1, 2, 3, 4, 5, tzinfo=TzInfo(UTC)) print(m.dimensions) #> (10, 20)

Delivery(timestamp='2020-01-02T03:04:05Z', dimensions=['10']) # (2)! `

  1. Set logfire record all both successful and failed validations, use record='failure' to only record failed validations, learn more.
  2. This will raise a ValidationError since there are too few dimensions, details of the input data and validation errors will be recorded in Logfire.

Would give you a view like this in the Logfire platform:

Logfire Pydantic Integration

This is just a toy example, but hopefully makes clear the potential value of instrumenting a more complex application.

Learn more about Pydantic Logfire

Why use Pydantic?¶

Installing Pydantic is as simple as: pip install pydantic

Pydantic examples¶

To see Pydantic at work, let's start with a simple example, creating a custom class that inherits from BaseModel:

Validation Successful

`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}, } """ `

  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.
  2. name is a string; because it has a default, it is not required.
  3. signup_ts is a 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.
  4. tastes is a dictionary with string keys and positive integer values. The PositiveInt type is shorthand for Annotated[int, annotated_types.Gt(0)].
  5. The input here is an ISO 8601 formatted datetime, but Pydantic will convert it to a datetime object.
  6. The key here is bytes, but Pydantic will take care of coercing it to a string.
  7. Similarly, Pydantic will coerce the string '1' to the integer 1.
  8. We create instance of User by passing our external data to User as keyword arguments.
  9. We can access fields as attributes of the model.
  10. We can convert the model to a dictionary with model_dump().

If validation fails, Pydantic will raise an error with a breakdown of what was wrong:

Validation Error

`# 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', }, ] """ `

  1. The input data is wrong here — id is not a valid integer, and signup_ts is missing.
  2. Trying to instantiate User will raise a ValidationError with a list of errors.

Who is using Pydantic?¶

Hundreds of organisations and packages are using Pydantic. Some of the prominent companies and organizations around the world who are using Pydantic include:

For a more comprehensive list of open-source projects using Pydantic see thelist of dependents on github, or you can find some awesome projects using Pydantic in awesome-pydantic.