Pydantic¶
zarr_metadata.pydantic is an optional integration.
- It requires Pydantic 2.13 or newer.
- The core package does not depend on Pydantic.
Each exported name is a Pydantic field type over one of the models. A raw
document given to the field goes through the same strict reader as
from_json. The value of the field is an instance of the model class
itself.
import json
from pydantic import BaseModel, TypeAdapter
import zarr_metadata.pydantic as zmp
with open("zarr.json", "rb") as f:
raw = json.load(f)
adapter: TypeAdapter[zmp.ZarrV3ArrayMetadataField] = TypeAdapter(zmp.ZarrV3ArrayMetadataField)
metadata = adapter.validate_python(raw)
encoded = metadata.to_key_value()["zarr.json"]
class ArrayManifest(BaseModel):
path: str
metadata: zmp.ZarrV3ArrayMetadataField
manifest = ArrayManifest.model_validate({"path": "a/b", "metadata": raw})
A static type checker sees manifest.metadata as a
zarr_metadata.model.ZarrV3ArrayMetadata.
A failed read raises a Pydantic ValidationError. It has one line error
per problem, in the format Pydantic uses for its own errors.
Choosing the context¶
A field type reads its document in the context given by Pydantic's validation context:
- If the validation context is a
Context, every field type of that format reads in it. - If it is a mapping:
- the v3 field types read in its
"zarr_metadata_context"item; - the v2 field types read in its
"zarr_metadata_context_v2"item.
- the v3 field types read in its
- If no context is given for a format, its field types read in that
format's default:
CORE_AND_EXTENSIONS_CONTEXTorCORE_V2_CONTEXT.
To pin a field to one context, annotate it with InScope. A field
annotated Annotated[ZarrV3ArrayMetadata, zmp.InScope(CONTEXT)] is read in
CONTEXT, whatever the validation context holds. A model instance given to
it is read again in CONTEXT.
A bare TypeAdapter is not a validator¶
A TypeAdapter over one of the public TypedDicts is a coercive shape
adapter. It is not a Zarr conformance validator. It may coerce values, or
discard fields that the strict reader rejects.
- It suits input built from Python objects, such as user-authored dicts.
- For JSON read from a store, use the field types above, or the readers directly.