Skip to main content

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): Converts inf and nan to null.
  • constants: Uses the JavaScript-style constants Infinity, -Infinity, and NaN (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_temporal overrides ser_json_timedelta. If you set ser_json_temporal='seconds', your timedelta objects will also be serialized as seconds, regardless of what ser_json_timedelta is set to.
  • Invalid JSON: Using ser_json_inf_nan='constants' produces output that standard JSON parsers (like Python's json.loads) may fail to parse unless they have specific extensions enabled.
  • Bytes Decoding: The default ser_json_bytes='utf8' will raise a UnicodeDecodeError during serialization if the bytes contain non-UTF-8 data. If your application handles arbitrary binary data, prefer base64 or hex.