Pydantic
Data validation using Python 3.6 type hinting
Samuel Colvin
from datetime import datetime
from typing import List
from pydantic import BaseModel
class User(BaseModel):
id: int
name = 'John Doe'
signup_ts: datetime = None
friends: List[int] = []
external_data = {
'id': '123',
'signup_ts': '2017-06-01 12:22',
'friends': [1, '2', b'3']
}
user = User(**external_data)
print(user.id) #> 123
print(repr(user.signup_ts)) #> datetime.datetime(2017, 6, 1, 12, 22)
print(friends) #> [1, 2, 3]
Basic Usage
from datetime import datetime
from typing import List
from pydantic import BaseModel
class User(BaseModel):
id: int
name = 'John Doe'
signup_ts: datetime = None
friends: List[int] = []
User(friends=['not int'])
#>
Traceback (most recent call last):
...
raise ValidationError(errors)
pydantic.exceptions.ValidationError: 2 errors validating input
id:
field required (error_type=Missing)
friends:
invalid literal for int() with
base 10: 'not int' (error_type=ValueError track=int)
Errors
from enum import Enum
from pydantic import BaseModel, validator
class FruitEnum(str, Enum):
pear = 'pear'
banana = 'banana'
class Foo(BaseModel):
count: int
size: float = None
class MyModel(BaseModel):
fruit: FruitEnum = FruitEnum.pear
foo: Foo
name: str
@validator('name')
def name_must_contain_space(cls, v):
if ' ' not in v:
raise ValueError('must contain a space')
return v.title()
Complex Types
Performance
Package | Relative Perf. | Validation Time |
---|---|---|
pydantic | 24.8μs | |
toasted-marshmallow | 1.6x slower | 39.5μs |
marshmallow | 1.9x slower | 47.4μs |
trafaret | 2.3x slower | 56.1μs |
django-restful-framework | 16.0x slower | 397.5μs |
-
no brainfuck - no new schema definition micro-language to learn.
-
python types - plays nicely with your IDE, linter and mypy
-
dual-use - settings (environment variable) validation and API data validation
-
Fast ...
Text
Rationale
Pydantic
By Samuel Colvin
Pydantic
Data validation using Python 3.6 type hinting
- 2,489