Global Serialization Configuration
To manage global serialization settings in pydantic-core, you use the CoreConfig class to define how types like dates, times, bytes, and special float values are converted to JSON.
Configuring Global Serialization
You can apply serialization settings by passing a CoreConfig dictionary to the SchemaSerializer constructor. This configuration dictates the output format for all fields within that schema.
from pydantic_core import SchemaSerializer, core_schema
# Define a schema for a dictionary containing bytes and floats
schema = core_schema.dict_schema(
keys_schema=core_schema.str_schema(),
values_schema=core_schema.any_schema()
)
# Configure global serialization: bytes as base64 and Inf/NaN as strings
config = core_schema.CoreConfig(
ser_json_bytes='base64',
ser_json_inf_nan='strings'
)
serializer = SchemaSerializer(schema, config=config)
data = {'data': b'hello', 'score': float('inf')}
json_output = serializer.to_json(data)
# b'{"data":"aGVsbG8=","score":"Infinity"}'
Temporal Serialization (Dates and Times)
The ser_json_temporal setting controls the serialization of datetime, date, time, and timedelta objects.
iso8601(default): Serializes to ISO 8601 strings.seconds: Serializes to Unix timestamps (float).milliseconds: Serializes to Unix timestamps in milliseconds (float).
from datetime import datetime
from pydantic_core import SchemaSerializer, core_schema
dt = datetime(2024, 1, 1, 12, 0)
schema = core_schema.datetime_schema()
# Serialize to Unix timestamp (seconds)
s = SchemaSerializer(schema, config={'ser_json_temporal': 'seconds'})
assert s.to_json(dt) == b'1704110400.0'
# Serialize to ISO 8601 (default)
s_default = SchemaSerializer(schema)
assert s_default.to_json(dt) == b'"2024-01-01T12:00:00"'
Precedence of Temporal Settings
If you need specific behavior for timedelta while keeping other temporal types as ISO 8601, use ser_json_timedelta. However, note that ser_json_temporal takes precedence if both are set.
from datetime import timedelta
from pydantic_core import SchemaSerializer, core_schema
td = timedelta(hours=1)
schema = core_schema.timedelta_schema()
# ser_json_timedelta allows 'iso8601' or 'float' (seconds)
s = SchemaSerializer(schema, config={'ser_json_timedelta': 'float'})
assert s.to_json(td) == b'3600.0'
Binary Data Serialization
The ser_json_bytes setting defines how bytes objects are represented in JSON.
utf8(default): Attempts to decode bytes as UTF-8; fails if bytes are not valid UTF-8.base64: Encodes bytes using Base64.hex: Encodes bytes as a hex string.
from pydantic_core import SchemaSerializer, core_schema
schema = core_schema.bytes_schema()
raw_data = b'\xff\xfe'
# Hex encoding
s_hex = SchemaSerializer(schema, config={'ser_json_bytes': 'hex'})
assert s_hex.to_json(raw_data) == b'"fffe"'
# Base64 encoding
s_b64 = SchemaSerializer(schema, config={'ser_json_bytes': 'base64'})
assert s_b64.to_json(raw_data) == b'"//4="'
Handling Infinity and NaN
By default, JSON does not support Infinity, -Infinity, or NaN. The ser_json_inf_nan setting determines how these float values are handled.
null(default): Convertsinfandnantonull.constants: Uses the JavaScript-style constantsInfinity,-Infinity, andNaN(Note: this is technically invalid JSON).strings: Wraps the constants in quotes (e.g.,"Infinity"), making it valid JSON.
from pydantic_core import SchemaSerializer, core_schema
schema = core_schema.float_schema()
val = float('inf')
# Default behavior (null)
s_null = SchemaSerializer(schema)
assert s_null.to_json(val) == b'null'
# String behavior
s_str = SchemaSerializer(schema, config={'ser_json_inf_nan': 'strings'})
assert s_str.to_json(val) == b'"Infinity"'
# Constant behavior
s_const = SchemaSerializer(schema, config={'ser_json_inf_nan': 'constants'})
assert s_const.to_json(val) == b'Infinity'
Troubleshooting and Gotchas
- Precedence:
ser_json_temporaloverridesser_json_timedelta. If you setser_json_temporal='seconds', yourtimedeltaobjects will also be serialized as seconds, regardless of whatser_json_timedeltais set to. - Invalid JSON: Using
ser_json_inf_nan='constants'produces output that standard JSON parsers (like Python'sjson.loads) may fail to parse unless they have specific extensions enabled. - Bytes Decoding: The default
ser_json_bytes='utf8'will raise aUnicodeDecodeErrorduring serialization if the bytes contain non-UTF-8 data. If your application handles arbitrary binary data, preferbase64orhex.