Skip to content

TypeAdapter

You may have types that are not BaseModels that you want to validate data against. Or you may want to validate a List[SomeModel], or dump it to JSON.

For use cases like this, Pydantic provides TypeAdapter, which can be used for type validation, serialization, and JSON schema generation without creating a BaseModel.

A TypeAdapter instance exposes some of the functionality from BaseModel instance methods for types that do not have such methods (such as dataclasses, primitive types, and more):

from typing import List

from typing_extensions import TypedDict

from pydantic import TypeAdapter, ValidationError

class User(TypedDict):
    name: str
    id: int

UserListValidator = TypeAdapter(List[User])
print(repr(UserListValidator.validate_python([{'name': 'Fred', 'id': '3'}])))
#> [{'name': 'Fred', 'id': 3}]

try:
    UserListValidator.validate_python(
        [{'name': 'Fred', 'id': 'wrong', 'other': 'no'}]
    )
except ValidationError as e:
    print(e)
    '''
    1 validation error for list[typed-dict]
    0.id
      Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='wrong', input_type=str]
    '''
Note

Despite some overlap in use cases with RootModel, TypeAdapter should not be used as a type annotation for specifying fields of a BaseModel, etc.

Parsing data into a specified type

TypeAdapter can be used to apply the parsing logic to populate Pydantic models in a more ad-hoc way. This function behaves similarly to BaseModel.model_validate, but works with arbitrary Pydantic-compatible types.

This is especially useful when you want to parse results into a type that is not a direct subclass of BaseModel. For example:

from typing import List

from pydantic import BaseModel, TypeAdapter

class Item(BaseModel):
    id: int
    name: str

# `item_data` could come from an API call, eg., via something like:
# item_data = requests.get('https://my-api.com/items').json()
item_data = [{'id': 1, 'name': 'My Item'}]

items = TypeAdapter(List[Item]).validate_python(item_data)
print(items)
#> [Item(id=1, name='My Item')]

TypeAdapter is capable of parsing data into any of the types Pydantic can handle as fields of a BaseModel.

TypeAdapter

TypeAdapter(type, *, config=None, _parent_depth=2)

Bases: Generic[T]

Type adapters provide a flexible way to perform validation and serialization based on a Python type.

A TypeAdapter instance exposes some of the functionality from BaseModel instance methods for types that do not have such methods (such as dataclasses, primitive types, and more).

Note that TypeAdapter is not an actual type, so you cannot use it in type annotations.

Attributes:

Name Type Description
core_schema

The core schema for the type.

validator SchemaValidator

The schema validator for the type.

serializer

The schema serializer for the type.

Source code in pydantic/type_adapter.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
def __init__(self, type: Any, *, config: ConfigDict | None = None, _parent_depth: int = 2) -> None:
    """Initializes the TypeAdapter object."""
    config_wrapper = _config.ConfigWrapper(config)

    try:
        type_has_config = issubclass(type, BaseModel) or is_dataclass(type) or is_typeddict(type)
    except TypeError:
        # type is not a class
        type_has_config = False

    if type_has_config and config is not None:
        raise PydanticUserError(
            'Cannot use `config` when the type is a BaseModel, dataclass or TypedDict.'
            ' These types can have their own config and setting the config via the `config`'
            ' parameter to TypeAdapter will not override it, thus the `config` you passed to'
            ' TypeAdapter becomes meaningless, which is probably not what you want.',
            code='type-adapter-config-unused',
        )

    core_schema: CoreSchema
    try:
        core_schema = _getattr_no_parents(type, '__pydantic_core_schema__')
    except AttributeError:
        core_schema = _get_schema(type, config_wrapper, parent_depth=_parent_depth + 1)

    core_schema = _discriminated_union.apply_discriminators(_core_utils.simplify_schema_references(core_schema))

    core_schema = _core_utils.validate_core_schema(core_schema)

    core_config = config_wrapper.core_config(None)
    validator: SchemaValidator
    try:
        validator = _getattr_no_parents(type, '__pydantic_validator__')
    except AttributeError:
        validator = create_schema_validator(core_schema, core_config, config_wrapper.plugin_settings)

    serializer: SchemaSerializer
    try:
        serializer = _getattr_no_parents(type, '__pydantic_serializer__')
    except AttributeError:
        serializer = SchemaSerializer(core_schema, core_config)

    self.core_schema = core_schema
    self.validator = validator
    self.serializer = serializer

validate_python

validate_python(
    __object,
    *,
    strict=None,
    from_attributes=None,
    context=None
)

Validate a Python object against the model.

Parameters:

Name Type Description Default
__object Any

The Python object to validate against the model.

required
strict bool | None

Whether to strictly check types.

None
from_attributes bool | None

Whether to extract data from object attributes.

None
context dict[str, Any] | None

Additional context to pass to the validator.

None

Returns:

Type Description
T

The validated object.

Source code in pydantic/type_adapter.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
def validate_python(
    self,
    __object: Any,
    *,
    strict: bool | None = None,
    from_attributes: bool | None = None,
    context: dict[str, Any] | None = None,
) -> T:
    """Validate a Python object against the model.

    Args:
        __object: The Python object to validate against the model.
        strict: Whether to strictly check types.
        from_attributes: Whether to extract data from object attributes.
        context: Additional context to pass to the validator.

    Returns:
        The validated object.
    """
    return self.validator.validate_python(__object, strict=strict, from_attributes=from_attributes, context=context)

validate_json

validate_json(__data, *, strict=None, context=None)

Validate a JSON string or bytes against the model.

Parameters:

Name Type Description Default
__data str | bytes

The JSON data to validate against the model.

required
strict bool | None

Whether to strictly check types.

None
context dict[str, Any] | None

Additional context to use during validation.

None

Returns:

Type Description
T

The validated object.

Source code in pydantic/type_adapter.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
def validate_json(
    self, __data: str | bytes, *, strict: bool | None = None, context: dict[str, Any] | None = None
) -> T:
    """Validate a JSON string or bytes against the model.

    Args:
        __data: The JSON data to validate against the model.
        strict: Whether to strictly check types.
        context: Additional context to use during validation.

    Returns:
        The validated object.
    """
    return self.validator.validate_json(__data, strict=strict, context=context)

validate_strings

validate_strings(__obj, *, strict=None, context=None)

Validate object contains string data against the model.

Parameters:

Name Type Description Default
__obj Any

The object contains string data to validate.

required
strict bool | None

Whether to strictly check types.

None
context dict[str, Any] | None

Additional context to use during validation.

None

Returns:

Type Description
T

The validated object.

Source code in pydantic/type_adapter.py
300
301
302
303
304
305
306
307
308
309
310
311
def validate_strings(self, __obj: Any, *, strict: bool | None = None, context: dict[str, Any] | None = None) -> T:
    """Validate object contains string data against the model.

    Args:
        __obj: The object contains string data to validate.
        strict: Whether to strictly check types.
        context: Additional context to use during validation.

    Returns:
        The validated object.
    """
    return self.validator.validate_strings(__obj, strict=strict, context=context)

get_default_value

get_default_value(*, strict=None, context=None)

Get the default value for the wrapped type.

Parameters:

Name Type Description Default
strict bool | None

Whether to strictly check types.

None
context dict[str, Any] | None

Additional context to pass to the validator.

None

Returns:

Type Description
Some[T] | None

The default value wrapped in a Some if there is one or None if not.

Source code in pydantic/type_adapter.py
313
314
315
316
317
318
319
320
321
322
323
def get_default_value(self, *, strict: bool | None = None, context: dict[str, Any] | None = None) -> Some[T] | None:
    """Get the default value for the wrapped type.

    Args:
        strict: Whether to strictly check types.
        context: Additional context to pass to the validator.

    Returns:
        The default value wrapped in a `Some` if there is one or None if not.
    """
    return self.validator.get_default_value(strict=strict, context=context)

dump_python

dump_python(
    __instance,
    *,
    mode="python",
    include=None,
    exclude=None,
    by_alias=False,
    exclude_unset=False,
    exclude_defaults=False,
    exclude_none=False,
    round_trip=False,
    warnings=True
)

Dump an instance of the adapted type to a Python object.

Parameters:

Name Type Description Default
__instance T

The Python object to serialize.

required
mode Literal['json', 'python']

The output format.

'python'
include IncEx | None

Fields to include in the output.

None
exclude IncEx | None

Fields to exclude from the output.

None
by_alias bool

Whether to use alias names for field names.

False
exclude_unset bool

Whether to exclude unset fields.

False
exclude_defaults bool

Whether to exclude fields with default values.

False
exclude_none bool

Whether to exclude fields with None values.

False
round_trip bool

Whether to output the serialized data in a way that is compatible with deserialization.

False
warnings bool

Whether to display serialization warnings.

True

Returns:

Type Description
Any

The serialized object.

Source code in pydantic/type_adapter.py
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
def dump_python(
    self,
    __instance: T,
    *,
    mode: Literal['json', 'python'] = 'python',
    include: IncEx | None = None,
    exclude: IncEx | None = None,
    by_alias: bool = False,
    exclude_unset: bool = False,
    exclude_defaults: bool = False,
    exclude_none: bool = False,
    round_trip: bool = False,
    warnings: bool = True,
) -> Any:
    """Dump an instance of the adapted type to a Python object.

    Args:
        __instance: The Python object to serialize.
        mode: The output format.
        include: Fields to include in the output.
        exclude: Fields to exclude from the output.
        by_alias: Whether to use alias names for field names.
        exclude_unset: Whether to exclude unset fields.
        exclude_defaults: Whether to exclude fields with default values.
        exclude_none: Whether to exclude fields with None values.
        round_trip: Whether to output the serialized data in a way that is compatible with deserialization.
        warnings: Whether to display serialization warnings.

    Returns:
        The serialized object.
    """
    return self.serializer.to_python(
        __instance,
        mode=mode,
        by_alias=by_alias,
        include=include,
        exclude=exclude,
        exclude_unset=exclude_unset,
        exclude_defaults=exclude_defaults,
        exclude_none=exclude_none,
        round_trip=round_trip,
        warnings=warnings,
    )

dump_json

dump_json(
    __instance,
    *,
    indent=None,
    include=None,
    exclude=None,
    by_alias=False,
    exclude_unset=False,
    exclude_defaults=False,
    exclude_none=False,
    round_trip=False,
    warnings=True
)

Serialize an instance of the adapted type to JSON.

Parameters:

Name Type Description Default
__instance T

The instance to be serialized.

required
indent int | None

Number of spaces for JSON indentation.

None
include IncEx | None

Fields to include.

None
exclude IncEx | None

Fields to exclude.

None
by_alias bool

Whether to use alias names for field names.

False
exclude_unset bool

Whether to exclude unset fields.

False
exclude_defaults bool

Whether to exclude fields with default values.

False
exclude_none bool

Whether to exclude fields with a value of None.

False
round_trip bool

Whether to serialize and deserialize the instance to ensure round-tripping.

False
warnings bool

Whether to emit serialization warnings.

True

Returns:

Type Description
bytes

The JSON representation of the given instance as bytes.

Source code in pydantic/type_adapter.py
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
def dump_json(
    self,
    __instance: T,
    *,
    indent: int | None = None,
    include: IncEx | None = None,
    exclude: IncEx | None = None,
    by_alias: bool = False,
    exclude_unset: bool = False,
    exclude_defaults: bool = False,
    exclude_none: bool = False,
    round_trip: bool = False,
    warnings: bool = True,
) -> bytes:
    """Serialize an instance of the adapted type to JSON.

    Args:
        __instance: The instance to be serialized.
        indent: Number of spaces for JSON indentation.
        include: Fields to include.
        exclude: Fields to exclude.
        by_alias: Whether to use alias names for field names.
        exclude_unset: Whether to exclude unset fields.
        exclude_defaults: Whether to exclude fields with default values.
        exclude_none: Whether to exclude fields with a value of `None`.
        round_trip: Whether to serialize and deserialize the instance to ensure round-tripping.
        warnings: Whether to emit serialization warnings.

    Returns:
        The JSON representation of the given instance as bytes.
    """
    return self.serializer.to_json(
        __instance,
        indent=indent,
        include=include,
        exclude=exclude,
        by_alias=by_alias,
        exclude_unset=exclude_unset,
        exclude_defaults=exclude_defaults,
        exclude_none=exclude_none,
        round_trip=round_trip,
        warnings=warnings,
    )

json_schema

json_schema(
    *,
    by_alias=True,
    ref_template=DEFAULT_REF_TEMPLATE,
    schema_generator=GenerateJsonSchema,
    mode="validation"
)

Generate a JSON schema for the adapted type.

Parameters:

Name Type Description Default
by_alias bool

Whether to use alias names for field names.

True
ref_template str

The format string used for generating $ref strings.

DEFAULT_REF_TEMPLATE
schema_generator type[GenerateJsonSchema]

The generator class used for creating the schema.

GenerateJsonSchema
mode JsonSchemaMode

The mode to use for schema generation.

'validation'

Returns:

Type Description
dict[str, Any]

The JSON schema for the model as a dictionary.

Source code in pydantic/type_adapter.py
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
def json_schema(
    self,
    *,
    by_alias: bool = True,
    ref_template: str = DEFAULT_REF_TEMPLATE,
    schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema,
    mode: JsonSchemaMode = 'validation',
) -> dict[str, Any]:
    """Generate a JSON schema for the adapted type.

    Args:
        by_alias: Whether to use alias names for field names.
        ref_template: The format string used for generating $ref strings.
        schema_generator: The generator class used for creating the schema.
        mode: The mode to use for schema generation.

    Returns:
        The JSON schema for the model as a dictionary.
    """
    schema_generator_instance = schema_generator(by_alias=by_alias, ref_template=ref_template)
    return schema_generator_instance.generate(self.core_schema, mode=mode)

json_schemas staticmethod

json_schemas(
    __inputs,
    *,
    by_alias=True,
    title=None,
    description=None,
    ref_template=DEFAULT_REF_TEMPLATE,
    schema_generator=GenerateJsonSchema
)

Generate a JSON schema including definitions from multiple type adapters.

Parameters:

Name Type Description Default
__inputs Iterable[tuple[JsonSchemaKeyT, JsonSchemaMode, TypeAdapter[Any]]]

Inputs to schema generation. The first two items will form the keys of the (first) output mapping; the type adapters will provide the core schemas that get converted into definitions in the output JSON schema.

required
by_alias bool

Whether to use alias names.

True
title str | None

The title for the schema.

None
description str | None

The description for the schema.

None
ref_template str

The format string used for generating $ref strings.

DEFAULT_REF_TEMPLATE
schema_generator type[GenerateJsonSchema]

The generator class used for creating the schema.

GenerateJsonSchema

Returns:

Type Description
tuple[dict[tuple[JsonSchemaKeyT, JsonSchemaMode], JsonSchemaValue], JsonSchemaValue]

A tuple where:

  • The first element is a dictionary whose keys are tuples of JSON schema key type and JSON mode, and whose values are the JSON schema corresponding to that pair of inputs. (These schemas may have JsonRef references to definitions that are defined in the second returned element.)
  • The second element is a JSON schema containing all definitions referenced in the first returned element, along with the optional title and description keys.
Source code in pydantic/type_adapter.py
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
@staticmethod
def json_schemas(
    __inputs: Iterable[tuple[JsonSchemaKeyT, JsonSchemaMode, TypeAdapter[Any]]],
    *,
    by_alias: bool = True,
    title: str | None = None,
    description: str | None = None,
    ref_template: str = DEFAULT_REF_TEMPLATE,
    schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema,
) -> tuple[dict[tuple[JsonSchemaKeyT, JsonSchemaMode], JsonSchemaValue], JsonSchemaValue]:
    """Generate a JSON schema including definitions from multiple type adapters.

    Args:
        __inputs: Inputs to schema generation. The first two items will form the keys of the (first)
            output mapping; the type adapters will provide the core schemas that get converted into
            definitions in the output JSON schema.
        by_alias: Whether to use alias names.
        title: The title for the schema.
        description: The description for the schema.
        ref_template: The format string used for generating $ref strings.
        schema_generator: The generator class used for creating the schema.

    Returns:
        A tuple where:

            - The first element is a dictionary whose keys are tuples of JSON schema key type and JSON mode, and
                whose values are the JSON schema corresponding to that pair of inputs. (These schemas may have
                JsonRef references to definitions that are defined in the second returned element.)
            - The second element is a JSON schema containing all definitions referenced in the first returned
                element, along with the optional title and description keys.

    """
    schema_generator_instance = schema_generator(by_alias=by_alias, ref_template=ref_template)

    inputs = [(key, mode, adapter.core_schema) for key, mode, adapter in __inputs]

    json_schemas_map, definitions = schema_generator_instance.generate_definitions(inputs)

    json_schema: dict[str, Any] = {}
    if definitions:
        json_schema['$defs'] = definitions
    if title:
        json_schema['title'] = title
    if description:
        json_schema['description'] = description

    return json_schemas_map, json_schema