from typing import List
from pydantic import BaseModel
class Foo(BaseModel):
count: int
size: float = None
class Bar(BaseModel):
apple = 'x'
banana = 'y'
class Spam(BaseModel):
foo: Foo
bars: List[Bar]
from typing import Generic, TypeVar, Optional, List
from pydantic import BaseModel, validator, ValidationError
from pydantic.generics import GenericModel
DataT = TypeVar('DataT')
class Error(BaseModel):
code: int
message: str
class DataModel(BaseModel):
numbers: List[int]
people: List[str]
class Response(GenericModel, Generic[DataT]):
data: Optional[DataT]
error: Optional[Error]
@validator('error', always=True)
def check_consistency(cls, v, values):
if v is not None and values['data'] is not None:
raise ValueError('must not provide both data and error')
if v is None and values.get('data') is None:
raise ValueError('must provide data or error')
return v
data = DataModel(numbers=[1, 2, 3], people=[])
error = Error(code=404, message='Not found')
print(Response[int](data=1))
#> data=1 error=None
print(Response[str](data='value'))
#> data='value' error=None
print(Response[str](data='value').dict())
#> {'data': 'value', 'error': None}
print(Response[DataModel](data=data).dict())
"""
{
'data': {'numbers': [1, 2, 3], 'people': []},
'error': None,
}
"""
print(Response[DataModel](error=error).dict())
"""
{
'data': None,
'error': {'code': 404, 'message': 'Not found'},
}
"""
try:
Response[int](data='value')
except ValidationError as e:
print(e)
"""
2 validation errors for Response[int]
data
value is not a valid integer (type=type_error.integer)
error
must provide data or error (type=value_error)
"""
from pydantic import BaseModel, ValidationError, validator
class UserModel(BaseModel):
name: str
username: str
password1: str
password2: str
@validator('name')
def name_must_contain_space(cls, v):
if ' ' not in v:
raise ValueError('must contain a space')
return v.title()
@validator('password2')
def passwords_match(cls, v, values, **kwargs):
if 'password1' in values and v != values['password1']:
raise ValueError('passwords do not match')
return v
@validator('username')
def username_alphanumeric(cls, v):
assert v.isalnum(), 'must be alphanumeric'
return v
user = UserModel(
name='samuel colvin',
username='scolvin',
password1='zxcvbn',
password2='zxcvbn',
)
print(user)
#> name='Samuel Colvin' username='scolvin' password1='zxcvbn' password2='zxcvbn'
try:
UserModel(
name='samuel',
username='scolvin',
password1='zxcvbn',
password2='zxcvbn2',
)
except ValidationError as e:
print(e)
"""
2 validation errors for UserModel
name
must contain a space (type=value_error)
password2
passwords do not match (type=value_error)
"""
from typing import List
from pydantic import BaseModel, ValidationError, validator
class ParentModel(BaseModel):
names: List[str]
class ChildModel(ParentModel):
@validator('names', each_item=True)
def check_names_not_empty(cls, v):
assert v != '', 'Empty strings are not allowed.'
return v
# This will NOT raise a ValidationError because the validator was not called
try:
child = ChildModel(names=['Alice', 'Bob', 'Eve', ''])
except ValidationError as e:
print(e)
else:
print('No ValidationError caught.')
#> No ValidationError caught.
class ChildModel2(ParentModel):
@validator('names')
def check_names_not_empty(cls, v):
for name in v:
assert name != '', 'Empty strings are not allowed.'
return v
try:
child = ChildModel2(names=['Alice', 'Bob', 'Eve', ''])
except ValidationError as e:
print(e)
"""
1 validation error for ChildModel2
names
Empty strings are not allowed. (type=assertion_error)
"""
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, NoneStr
class Model(BaseModel):
age: int
first_name = 'John'
last_name: NoneStr = None
signup_ts: Optional[datetime] = None
list_of_ints: List[int]
m = Model(age=42, list_of_ints=[1, '2', b'3'])
print(m.middle_name) # not a model field!
Model() # will raise a validation error for age and list_of_ints
在没有任何特殊配置的情况下,mypy 会捕获其中一个错误:
13: error: "Model" has no attribute "middle_name"
启用插件后,它会同时捕获:
13: error: "Model" has no attribute "middle_name" 16: error: Missing named argument "age" for "Model" 16: error: Missing named argument "list_of_ints" for "Model"
from typing import List
from pydantic import BaseModel
class Foo(BaseModel):
count: int
size: float = None
class Bar(BaseModel):
apple = 'x'
banana = 'y'
class Spam(BaseModel):
foo: Foo
bars: List[Bar]
from typing import Generic, TypeVar, Optional, List
from pydantic import BaseModel, validator, ValidationError
from pydantic.generics import GenericModel
DataT = TypeVar('DataT')
class Error(BaseModel):
code: int
message: str
class DataModel(BaseModel):
numbers: List[int]
people: List[str]
class Response(GenericModel, Generic[DataT]):
data: Optional[DataT]
error: Optional[Error]
@validator('error', always=True)
def check_consistency(cls, v, values):
if v is not None and values['data'] is not None:
raise ValueError('must not provide both data and error')
if v is None and values.get('data') is None:
raise ValueError('must provide data or error')
return v
data = DataModel(numbers=[1, 2, 3], people=[])
error = Error(code=404, message='Not found')
print(Response[int](data=1))
#> data=1 error=None
print(Response[str](data='value'))
#> data='value' error=None
print(Response[str](data='value').dict())
#> {'data': 'value', 'error': None}
print(Response[DataModel](data=data).dict())
"""
{
'data': {'numbers': [1, 2, 3], 'people': []},
'error': None,
}
"""
print(Response[DataModel](error=error).dict())
"""
{
'data': None,
'error': {'code': 404, 'message': 'Not found'},
}
"""
try:
Response[int](data='value')
except ValidationError as e:
print(e)
"""
2 validation errors for Response[int]
data
value is not a valid integer (type=type_error.integer)
error
must provide data or error (type=value_error)
"""
from pydantic import BaseModel, ValidationError, validator
class UserModel(BaseModel):
name: str
username: str
password1: str
password2: str
@validator('name')
def name_must_contain_space(cls, v):
if ' ' not in v:
raise ValueError('must contain a space')
return v.title()
@validator('password2')
def passwords_match(cls, v, values, **kwargs):
if 'password1' in values and v != values['password1']:
raise ValueError('passwords do not match')
return v
@validator('username')
def username_alphanumeric(cls, v):
assert v.isalnum(), 'must be alphanumeric'
return v
user = UserModel(
name='samuel colvin',
username='scolvin',
password1='zxcvbn',
password2='zxcvbn',
)
print(user)
#> name='Samuel Colvin' username='scolvin' password1='zxcvbn' password2='zxcvbn'
try:
UserModel(
name='samuel',
username='scolvin',
password1='zxcvbn',
password2='zxcvbn2',
)
except ValidationError as e:
print(e)
"""
2 validation errors for UserModel
name
must contain a space (type=value_error)
password2
passwords do not match (type=value_error)
"""
from typing import List
from pydantic import BaseModel, ValidationError, validator
class ParentModel(BaseModel):
names: List[str]
class ChildModel(ParentModel):
@validator('names', each_item=True)
def check_names_not_empty(cls, v):
assert v != '', 'Empty strings are not allowed.'
return v
# This will NOT raise a ValidationError because the validator was not called
try:
child = ChildModel(names=['Alice', 'Bob', 'Eve', ''])
except ValidationError as e:
print(e)
else:
print('No ValidationError caught.')
#> No ValidationError caught.
class ChildModel2(ParentModel):
@validator('names')
def check_names_not_empty(cls, v):
for name in v:
assert name != '', 'Empty strings are not allowed.'
return v
try:
child = ChildModel2(names=['Alice', 'Bob', 'Eve', ''])
except ValidationError as e:
print(e)
"""
1 validation error for ChildModel2
names
Empty strings are not allowed. (type=assertion_error)
"""
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, NoneStr
class Model(BaseModel):
age: int
first_name = 'John'
last_name: NoneStr = None
signup_ts: Optional[datetime] = None
list_of_ints: List[int]
m = Model(age=42, list_of_ints=[1, '2', b'3'])
print(m.middle_name) # not a model field!
Model() # will raise a validation error for age and list_of_ints
在没有任何特殊配置的情况下,mypy 会捕获其中一个错误:
13: error: "Model" has no attribute "middle_name"
启用插件后,它会同时捕获:
13: error: "Model" has no attribute "middle_name" 16: error: Missing named argument "age" for "Model" 16: error: Missing named argument "list_of_ints" for "Model"