field_validator decorator signature
The field_validator decorator is used to define validation for specific model fields. It is applied as @field_validator('field_name') above a classmethod. The method receives the field value as parameter v and a ValidationInfo object as parameter info, and returns the validated value or raises ValueError.
ValidationInfo context in field_validator
The ValidationInfo object passed to a field_validator method contains a context attribute that provides validation context passed when the model is instantiated. This context is not sent to LLMs and can be used within validators to access external configuration or allowlists.
Field serializer decorator signature
The @field_serializer decorator is used to customize field serialization. Signature: @field_serializer(*fields: str | Literal['*'], mode: str = 'plain', check_fields: bool = True, return_type: type | None = None). Parameters: fields are the field names to serialize (supports '*' for all fields), mode is 'plain' (default) or 'wrap', check_fields validates field names exist during class creation, return_type enforces serialization output type.
field_serializer with mode='plain' example
from typing import Any
from pydantic import BaseModel, field_serializer
class Model(BaseModel):
number: int
@field_serializer('number', mode='plain')
def ser_number(self, value: Any) -> Any:
if isinstance(value, int):
return value * 2
else:
return value
print(Model(number=4).model_dump())
#> {'number': 8}
field_serializer with mode='wrap' example
from typing import Any
from pydantic import BaseModel, SerializerFunctionWrapHandler, field_serializer
class Model(BaseModel):
number: int
@field_serializer('number', mode='wrap')
def ser_number(
self, value: Any, handler: SerializerFunctionWrapHandler
) -> int:
return handler(value) + 1
print(Model(number=4).model_dump())
#> {'number': 5}
model_serializer decorator signature
The @model_serializer decorator customizes serialization for the entire model. Signature: @model_serializer(mode: str = 'plain', return_type: type | None = None). Parameters: mode is 'plain' (default, called unconditionally) or 'wrap' (allows code before/after Pydantic logic), return_type enforces serialization output type.
model_serializer with mode='plain' example
from pydantic import BaseModel, model_serializer
class UserModel(BaseModel):
username: str
password: str
@model_serializer(mode='plain')
def serialize_model(self) -> str:
return f'{self.username} - {self.password}'
print(UserModel(username='foo', password='bar').model_dump())
#> foo - bar
model_serializer with mode='wrap' example
from pydantic import BaseModel, SerializerFunctionWrapHandler, model_serializer
class UserModel(BaseModel):
username: str
password: str
@model_serializer(mode='wrap')
def serialize_model(
self, handler: SerializerFunctionWrapHandler
) -> dict[str, object]:
serialized = handler(self)
serialized['fields'] = list(serialized)
return serialized
print(UserModel(username='foo', password='bar').model_dump())
#> {'username': 'foo', 'password': 'bar', 'fields': ['username', 'password']}
Field serializer applied to multiple fields
from pydantic import BaseModel, field_serializer
class Model(BaseModel):
f1: str
f2: str
@field_serializer('f1', 'f2', mode='plain')
def capitalize(self, value: str) -> str:
return value.capitalize()
validate_call decorator basic usage
The validate_call() decorator allows arguments passed to a function to be parsed and validated using the function's annotations before the function is called. It uses model creation and initialization under the hood and provides an easy way to apply validation with minimal boilerplate.
validate_call parameter type coercion
Parameter types are inferred from type annotations on the function, or as Any if not annotated. Types are by default coerced by the decorator before they are passed to the actual function. For example, a string '2000-01-01' will be converted to a date object if the parameter is annotated as date type.
validate_call return value validation
By default, the return value of the function is not validated. To validate the return value, the validate_return argument of the decorator can be set to True.
validate_call supported function signatures
The validate_call() decorator is designed to work with functions using all possible parameter configurations: positional or keyword parameters with or without defaults, keyword-only parameters (after *,), positional-only parameters (before /), variable positional parameters (*args), and variable keyword parameters (**kwargs).
validate_call with Unpack for typed dictionaries
Unpack and typed dictionaries can be used to annotate the variable keyword parameters of a function decorated with validate_call. This allows structured validation of **kwargs parameters. Added in v2.10.
validate_call with Field function
The Field() function can be used with the validate_call decorator to provide extra information about fields and validations. When not using default or default_factory parameters, the Annotated pattern is recommended. Field() can be used as a default value to trick type checkers into thinking a default value is provided for a required parameter.
validate_call raw_function attribute
The original function decorated with validate_call can be accessed using the raw_function attribute. This is useful when you trust your input arguments and want to call the function in the most efficient way without validation overhead.
validate_call with async functions
The validate_call() decorator can be used on async functions. It performs the same validation on arguments and can validate return values in async contexts.
validate_call type checker compatibility
The validate_call() decorator preserves the decorated function's signature and should be compatible with type checkers like mypy and pyright. However, raw_function and other added attributes won't be recognized by type checkers and will require error suppression using type: ignore comments.
validate_call custom configuration
The config parameter of the validate_call decorator can be used to specify a custom configuration, similar to Pydantic models. Configuration is passed as a ConfigDict object, for example: @validate_call(config=ConfigDict(arbitrary_types_allowed=True))
validate_call validation exception behavior
Upon validation failure, a standard Pydantic ValidationError is raised. This is also true for missing required arguments, where Python normally raises TypeError. The error identifies the argument and value that were rejected.
validate_call performance considerations
While the inspection of the decorated function is only performed once, there will be a performance impact when making calls to the function compared to using the original function. validate_call is not an equivalent or alternative to function definitions in strongly typed languages.
validate_call example with basic types
Example showing validate_call with a function that has string and integer parameters, with type coercion:
```python
from pydantic import ValidationError, validate_call
@validate_call
def repeat(s: str, count: int, *, separator: bytes = b'') -> bytes:
b = s.encode()
return separator.join(b for _ in range(count))
a = repeat('hello', 3)
print(a)
#> b'hellohellohello'
b = repeat('x', '4', separator=b' ')
print(b)
#> b'x x x x'
try:
c = repeat('hello', 'wrong')
except ValidationError as exc:
print(exc)
```
validate_call example with date coercion
Example showing validate_call coercing string to date type:
```python
from datetime import date
from pydantic import validate_call
@validate_call
def greater_than(d1: date, d2: date, *, include_equal=False) -> date:
if include_equal:
return d1 >= d2
else:
return d1 > d2
d1 = '2000-01-01' # string converted to date
d2 = date(2001, 1, 1)
greater_than(d1, d2, include_equal=True)
```
validate_call example with all parameter types
Example showing validate_call with positional-only, positional-or-keyword, keyword-only, *args, and **kwargs:
```python
from pydantic import validate_call
@validate_call
def armageddon(
a: int,
/,
b: int,
*c: int,
d: int,
e: int = None,
**f: int,
) -> str:
return f'a={a} b={b} c={c} d={d} e={e} f={f}'
print(armageddon(1, 2, d=3))
#> a=1 b=2 c=() d=3 e=None f={}
print(armageddon(1, 2, 3, 4, 5, 6, d=8, e=9, f=10, spam=11))
#> a=1 b=2 c=(3, 4, 5, 6) d=8 e=9 f={'f': 10, 'spam': 11}
```
validate_call example with Unpack and TypedDict
Example showing validate_call with Unpack and TypedDict for structured **kwargs:
```python
from typing_extensions import TypedDict, Unpack
from pydantic import validate_call
class Point(TypedDict):
x: int
y: int
@validate_call
def add_coords(**kwargs: Unpack[Point]) -> int:
return kwargs['x'] + kwargs['y']
add_coords(x=1, y=2)
```
validate_call example with Field constraints
Example showing validate_call with Field constraints using Annotated:
```python
from typing import Annotated
from pydantic import Field, ValidationError, validate_call
@validate_call
def how_many(num: Annotated[int, Field(gt=10)]):
return num
try:
how_many(1)
except ValidationError as e:
print(e)
```
validate_call example with Field default
Example showing validate_call with Field providing a default value:
```python
from pydantic import Field, validate_call
@validate_call
def return_value(value: str = Field(default='default value')):
return value
print(return_value())
#> default value
```
validate_call example with alias
Example showing validate_call with Field alias:
```python
from typing import Annotated
from pydantic import Field, validate_call
@validate_call
def how_many(num: Annotated[int, Field(gt=10, alias='number')]):
return num
how_many(number=42)
```
validate_call example accessing raw_function
Example showing how to access the original unvalidated function:
```python
from pydantic import validate_call
@validate_call
def repeat(s: str, count: int, *, separator: bytes = b'') -> bytes:
b = s.encode()
return separator.join(b for _ in range(count))
a = repeat('hello', 3)
print(a)
#> b'hellohellohello'
b = repeat.raw_function('good bye', 2, separator=b', ')
print(b)
#> b'good bye, good bye'
```
validate_call example with async function
Example showing validate_call with an async function:
```python
import asyncio
from pydantic import PositiveInt, ValidationError, validate_call
@validate_call
async def get_user_email(user_id: PositiveInt):
email = await conn.execute('select email from users where id=$1', user_id)
if email is None:
raise RuntimeError('user not found')
else:
return email
async def main():
email = await get_user_email(123)
print(email)
#> testing@example.com
try:
await get_user_email(-4)
except ValidationError as exc:
print(exc.errors())
asyncio.run(main())
```
validate_call example with ConfigDict
Example showing validate_call with custom configuration:
```python
from pydantic import ConfigDict, ValidationError, validate_call
class Foobar:
def __init__(self, v: str):
self.v = v
def __add__(self, other: 'Foobar') -> str:
return f'{self} + {other}'
def __str__(self) -> str:
return f'Foobar({self.v})'
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
def add_foobars(a: Foobar, b: Foobar):
return a + b
c = add_foobars(Foobar('a'), Foobar('b'))
print(c)
#> Foobar(a) + Foobar(b)
```
computed_field decorator
The @computed_field decorator includes properties or cached_property methods in model serialization and JSON schema (in serialization mode). The decorator should be stacked with @property or @cached_property. Pydantic does not perform validation or cache invalidation on computed fields. Starting in v2.13, computed fields support the exclude_if parameter.
computed_field example with volume calculation
from pydantic import BaseModel, computed_field
class Box(BaseModel):
width: float
height: float
depth: float
@computed_field
@property
def volume(self) -> float:
return self.width * self.height * self.depth
b = Box(width=1, height=2, depth=3)
print(b.model_dump())
#> {'width': 1.0, 'height': 2.0, 'depth': 3.0, 'volume': 6.0}