Skip to main content

TypedDict Schemas

To validate and serialize dictionary-like structures with a fixed set of keys in this codebase, you use typed_dict_schema to define the container and typed_dict_field to define individual field rules.

Basic Validation and Serialization

The following example demonstrates how to define a schema for a dictionary with specific keys and types, then use it to validate input and serialize output.

from pydantic_core import SchemaValidator, SchemaSerializer, core_schema

# Define the schema
schema = core_schema.typed_dict_schema(
{
'foo': core_schema.typed_dict_field(core_schema.int_schema()),
'bar': core_schema.typed_dict_field(core_schema.bytes_schema()),
}
)

# Validation
v = SchemaValidator(schema)
validated_data = v.validate_python({'foo': 1, 'bar': b'more'})
assert validated_data == {'foo': 1, 'bar': b'more'}

# Serialization
s = SchemaSerializer(schema)
assert s.to_python(validated_data) == {'foo': 1, 'bar': b'more'}

Configuring Field Requirements

By default, typed_dict_schema sets total=True, meaning all fields are required. You can override this at the schema level or for individual fields using the required parameter in typed_dict_field.

from pydantic_core import SchemaValidator, core_schema

schema = core_schema.typed_dict_schema(
{
# Explicitly required
'a': core_schema.typed_dict_field(core_schema.int_schema(), required=True),
# Explicitly optional
'b': core_schema.typed_dict_field(core_schema.int_schema(), required=False),
},
total=True # Default behavior for other fields
)

v = SchemaValidator(schema)
# Success: 'b' is missing but optional
assert v.validate_python({'a': 1}) == {'a': 1}

Mapping Input and Output Keys

You can use validation_alias to map different input keys to your internal field names, and serialization_alias to change the key name during serialization.

from pydantic_core import SchemaValidator, SchemaSerializer, core_schema

schema = core_schema.typed_dict_schema(
{
'cat': core_schema.typed_dict_field(
core_schema.int_schema(),
validation_alias='input_cat',
serialization_alias='Meow'
),
'dog': core_schema.typed_dict_field(
core_schema.int_schema(),
validation_alias=['animals', 'dog'] # Path lookup: animals -> dog
),
}
)

# Validation using aliases
v = SchemaValidator(schema)
input_data = {
'input_cat': 1,
'animals': {'dog': 2}
}
validated = v.validate_python(input_data)
assert validated == {'cat': 1, 'dog': 2}

# Serialization using aliases
s = SchemaSerializer(schema)
assert s.to_python(validated, by_alias=True) == {'Meow': 1, 'dog': 2}

Handling Extra Fields

The extra_behavior parameter determines how the validator handles keys that are not defined in the schema. It supports three modes: 'ignore', 'allow', and 'forbid'.

from pydantic_core import SchemaValidator, core_schema

schema = core_schema.typed_dict_schema(
{'foo': core_schema.typed_dict_field(core_schema.int_schema())},
extra_behavior='ignore' # Options: 'ignore', 'allow', 'forbid'
)

v = SchemaValidator(schema)
# 'bar' is ignored
assert v.validate_python({'foo': 1, 'bar': 2}) == {'foo': 1}

If you use extra_behavior='allow', you can also provide an extras_schema to validate the values of those extra fields.

Excluding Fields from Serialization

You can prevent specific fields from appearing in the serialized output using serialization_exclude or conditional logic with serialization_exclude_if.

from pydantic_core import SchemaSerializer, core_schema

schema = core_schema.typed_dict_schema(
{
'a': core_schema.typed_dict_field(core_schema.int_schema(), serialization_exclude=True),
'b': core_schema.typed_dict_field(
core_schema.int_schema(),
serialization_exclude_if=lambda v: v > 10
),
'c': core_schema.typed_dict_field(core_schema.int_schema()),
}
)

s = SchemaSerializer(schema)
data = {'a': 1, 'b': 100, 'c': 3}
# 'a' is always excluded, 'b' is excluded because 100 > 10
assert s.to_python(data) == {'c': 3}

Troubleshooting

  • Missing Keys: If a field is missing and not marked as required=False (or the schema is total=True), validation will fail with a missing error.
  • Extra Fields: If extra_behavior is not set, it defaults to the global extra_fields_behavior config (usually 'ignore'). If set to 'forbid', any unknown key will trigger an error.
  • Alias Complexity: validation_alias can be a list of lists (e.g., [['foo', 'bar'], ['baz']]) to provide multiple alternative paths for finding a value. The validator will try each path in order.