docs/concepts/config.md
The behaviour of Pydantic can be controlled via a variety of configuration values, documented
on the [ConfigDict][pydantic.ConfigDict] class. This page describes how configuration can be
specified for Pydantic's supported types.
On Pydantic models, configuration can be specified in two ways:
Using the [model_config][pydantic.BaseModel.model_config] class attribute:
from pydantic import BaseModel, ConfigDict, ValidationError
class Model(BaseModel):
model_config = ConfigDict(str_max_length=5) # (1)!
v: str
try:
m = Model(v='abcdef')
except ValidationError as e:
print(e)
"""
1 validation error for Model
v
String should have at most 5 characters [type=string_too_long, input_value='abcdef', input_type=str]
"""
{'str_max_length': 5}) can also be used.!!! note
In Pydantic V1, the Config class was used. This is still supported, but deprecated.
Using class arguments:
from pydantic import BaseModel
class Model(BaseModel, frozen=True):
a: str
Unlike the [model_config][pydantic.BaseModel.model_config] class attribute,
static type checkers will recognize class arguments. For frozen, any instance
mutation will be flagged as an type checking error.
Pydantic dataclasses also support configuration (read more in the dedicated section).
from pydantic import ConfigDict, ValidationError
from pydantic.dataclasses import dataclass
@dataclass(config=ConfigDict(str_max_length=10, validate_assignment=True))
class User:
name: str
user = User(name='John Doe')
try:
user.name = 'x' * 20
except ValidationError as e:
print(e)
"""
1 validation error for User
name
String should have at most 10 characters [type=string_too_long, input_value='xxxxxxxxxxxxxxxxxxxx', input_type=str]
"""
TypeAdapterType adapters (using the [TypeAdapter][pydantic.TypeAdapter] class) support configuration,
by providing the config argument.
from pydantic import ConfigDict, TypeAdapter
ta = TypeAdapter(list[str], config=ConfigDict(coerce_numbers_to_str=True))
print(ta.validate_python([1, 2]))
#> ['1', '2']
Configuration can't be provided if the type adapter directly wraps a type that support it, and a usage error is raised in this case. The configuration propagation rules also apply.
If you are using [standard library dataclasses][dataclasses] or [TypedDict][typing.TypedDict] classes,
the configuration can be set in two ways:
Using the __pydantic_config__ class attribute:
from dataclasses import dataclass
from pydantic import ConfigDict
@dataclass
class User:
__pydantic_config__ = ConfigDict(strict=True)
id: int
name: str = 'John Doe'
Using the [@with_config][pydantic.config.with_config] decorator (this avoids static type checking errors with
[TypedDict][typing.TypedDict]):
from typing_extensions import TypedDict
from pydantic import ConfigDict, with_config
@with_config(ConfigDict(str_to_lower=True))
class Model(TypedDict):
x: str
@validate_call decoratorThe @validate_call also supports setting custom configuration. See the
dedicated section for more details.
If you wish to change the behaviour of Pydantic globally, you can create your own custom parent class with a custom configuration, as the configuration is inherited:
from pydantic import BaseModel, ConfigDict
class Parent(BaseModel):
model_config = ConfigDict(extra='allow')
class Model(Parent):
x: str
m = Model(x='foo', y='bar')
print(m.model_dump())
#> {'x': 'foo', 'y': 'bar'}
If you provide configuration to the subclasses, it will be merged with the parent configuration:
from pydantic import BaseModel, ConfigDict
class Parent(BaseModel):
model_config = ConfigDict(extra='allow', str_to_lower=False)
class Model(Parent):
model_config = ConfigDict(str_to_lower=True)
x: str
m = Model(x='FOO', y='bar')
print(m.model_dump())
#> {'x': 'foo', 'y': 'bar'}
print(Model.model_config)
#> {'extra': 'allow', 'str_to_lower': True}
!!! warning If your model inherits from multiple bases, Pydantic currently doesn't follow the [MRO]. For more details, see this issue.
[MRO]: https://docs.python.org/3/glossary.html#term-method-resolution-order
When using types that support configuration as field annotations, configuration may not be propagated:
For Pydantic models and dataclasses, configuration will not be propagated, each model has its own "configuration boundary":
from pydantic import BaseModel, ConfigDict
class User(BaseModel):
name: str
class Parent(BaseModel):
user: User
model_config = ConfigDict(str_to_lower=True)
print(Parent(user={'name': 'JOHN'}))
#> user=User(name='JOHN')
For stdlib types (dataclasses and typed dictionaries), configuration will be propagated, unless the type has its own configuration set:
from dataclasses import dataclass
from pydantic import BaseModel, ConfigDict, with_config
@dataclass
class UserWithoutConfig:
name: str
@dataclass
@with_config(str_to_lower=False)
class UserWithConfig:
name: str
class Parent(BaseModel):
user_1: UserWithoutConfig
user_2: UserWithConfig
model_config = ConfigDict(str_to_lower=True)
print(Parent(user_1={'name': 'JOHN'}, user_2={'name': 'JOHN'}))
#> user_1=UserWithoutConfig(name='john') user_2=UserWithConfig(name='JOHN')