Writing ASDF Pydantic models to define tagged objects#
The AsdfPydanticModel is a class that combines the feature of
pydantic.BaseModel and ASDF
to be readily serializable an tagged object in ASDF.
class Rectangle(AsdfPydanticModel):
_tag = "asdf://asdf-pydantic/examples/tags/rectangle-1.0.0"
width: float
height: float
This Rectangle model will be referenced in ASDF’s YAML file as !rectangle-1.0.0
specified by the _tag field. _tag is a globally unique ASDF tag (see naming best
practices)
that identifies the ASDF Pydantic model. This model contains two fields: width and
height and their field type are both float.
Field Types#
ASDF field type#
An ASDF field type is a Python type that can be serialized to a YAML file. These include Python types that are
Compatible with ASDF Standard Schema:
class Employees(AsdfPydanticModel): _tag = "asdf://asdf-pydantic/examples/tags/employees-1.0.0" last_updated: datetime.datetime names: list[str]
example: !<asdf://asdf-pydantic/examples/tags/employees-1.0.0> last_updated: !time/time-1.2.0 "2000-12-31T13:05:27.737" names: ["alice", "bob", "charlie"]
ASDF tagged types from ASDF extensions:
from astropy import units as u class Rectangle(AsdfPydanticModel): _tag = "asdf://asdf-pydantic/examples/tags/rectangle-1.0.0" width: u.Quantity[u.m] height: u.Quantity[u.m]
rect: !<asdf://asdf-pydantic/examples/tags/rectangle-1.0.0> width: {datatype: float64, unit: !unit/unit-1.0.0 m, value: 1.0} height: {datatype: float64, unit: !unit/unit-1.0.0 m, value: 2.0}
Here, if
asdf-astropyis installed, then theQuantitytype is a valid ASDF tagged.A subtype of
AsdfPydanticModel:class Office(AsdfPydanticModel): _tag = "asdf://asdf-pydantic/examples/tags/office-1.0.0" employees: Employees
office: !<asdf://asdf-pydantic/examples/tags/office-1.0.0> employees: !<asdf://asdf-pydantic/examples/tags/employees-1.0.0> names: ["alice", "bob", "charlie"]
Because both
OfficeandEmployeesareAsdfPydanticModel, both are referenced by their tags.A subtype of
pydantic.BaseModel:from pydantic import BaseModel class Employees(BaseModel): names: list[str] class Office(AsdfPydanticModel): _tag = "asdf://asdf-pydantic/examples/tags/office-1.0.0" employees: Employees
office: !<asdf://asdf-pydantic/examples/tags/office-1.0.0> employees: names: ["alice", "bob", "charlie"]
Because
Employeesis not anAsdfPydanticModel, it is not reference by tag. If it’s fields are all recursively serializable, then it becomes an untagged ASDF object.
Custom field type#
You can define your own custom types in any way so that they would satisfy a ASDF field type. Here list a few options:
Create a tagged ASDF type classically (involves defining a custom ASDF Converter and extension).
Create a tagged ASDF type for composite types (e.g., dict-like,
dataclass,TypeDict,NamedTuple), define aAsdfPydanticModelCreate untagged type is not yet supported.