zarr-cm-tree
GeoZarr convention attribute builders — an opinionated bridge between pyproj and zarr-cm.
It produces the plain attribute dicts that make up the attributes block of a
Zarr v3 group or array for the GeoZarr conventions proj:, spatial: and
multiscales, plus an interim dggs: placeholder.
uv add zarr-cm-tree
Scope
zarr_cm owns the conventions themselves: schemas, validation, revisions, and
the zarr_conventions registry entries. This package adds only what it
deliberately does not:
- A pyproj bridge.
GeoZarrProjholds a canonicalpyproj.CRSand decides how to serialise it — authority code when one exists, WKT2 otherwise — and hands rioxarray a matching CRS string viario_input(). - Domain defaults for gridded data.
GeoZarrSpatialdefaults to("y", "x")dims and"pixel"registration, and inferstransform_type="affine". - Layout rules the schema does not encode, e.g.
derived_fromrequires atransform. geozarr_attrs, which emits several conventions at once together with a matchingzarr_conventionsregistry array, so the registry always describes exactly the conventions present.
Everything returned is a plain dict, never a model, so it merges straight into
xarray.Dataset.attrs.
Usage
import zarr_cm_tree as gz
crs = gz.GeoZarrProj.from_user_input("EPSG:27704") # Equi7Grid EU
spatial = gz.GeoZarrSpatial(
transform=(10.0, 0.0, 5400000.0, 0.0, -10.0, 2700000.0),
shape=(10000, 10000),
)
attrs = gz.geozarr_attrs(crs=crs, spatial=spatial)
# {"proj:code": "EPSG:27704", "spatial:transform": [...], "zarr_conventions": [...]}
group.attrs.update(attrs) # or ds.attrs.update(attrs)
Add a pyramid by passing the layout, one entry per level:
attrs = gz.geozarr_attrs(
crs=crs,
multiscales=[
{"asset": "0"},
{"asset": "1", "derived_from": "0", "transform": {"scale": [2.0, 2.0]}},
],
)
The individual builders (build_proj_attrs, build_spatial_attrs,
build_multiscales_attrs, build_zarr_conventions, merge_attrs) are public
too, for callers that want to assemble attrs themselves.
build_zarr_conventions accepts the legacy "geo-proj" spelling as an alias for
"proj", since zarr_cm.ConventionName still carries it and so do stores
written before the upstream rename.
Convention revisions
Each convention in zarr_cm ships at one or more numbered revisions. A
revision fixes the convention's JSON Schema: which attribute keys are legal, how
strictly they are validated, and the schema_url written into the store's
zarr_conventions array.
This package writes at whatever revision the installed zarr_cm declares
latest, rather than pinning one — a pin nobody updates goes stale, and every
store records the revision that wrote it in its own schema_url, so drift stays
auditable after the fact. Reading is unaffected either way:
zarr_cm.<convention>.detect() sniffs the revision from the store.
current_revisions() reports what is in use:
| Convention | Current | Notes |
|---|---|---|
proj: |
r3 |
r2 restricted proj:code to ^[A-Z]+:[0-9]+$, so OGC:CRS84 was invalid |
spatial: |
r3 |
same keys as r2, looser validation |
multiscales |
r2 |
the only revision published so far |
tests/test_conventions.py asserts these, so a zarr_cm upgrade that ships a
new revision surfaces as one failing test rather than silently changing what gets
written. When it fails: read what changed, confirm the new attributes are what
you want, update EXPECTED_REVISIONS. Stricter validation would fail loudly at
ingest anyway; the test is there for the revisions that change quietly.
Known issues
- Writing a CRS onto a group with no y/x spatial dims (e.g. HEALPix) produces a
bogus identity
GeoTransform. Carried over from cube-factory (ZarrGroup.to_datasetin_core.py); the fix belongs wherever the rioxarray-facing write path ends up living.
Development
uv sync --all-groups
just test # pytest
just check # ruff lint + format + ty
Metadata
Release files for zarr-cm-tree 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zarr_cm_tree-0.1.0.tar.gz | 9.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zarr_cm_tree-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.0 kB
Release files / zarr_cm_tree-0.1.0.tar.gz
| Download URL | zarr_cm_tree-0.1.0.tar.gz |
|---|---|
| Size | 9.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
64ebca2f130bc04a9c2c4982f4ed90c4ff7c18e26c3810969ee6d283bfff2d07
|
|
BLAKE2b-256 checksum How to use checksums |
9e10157508e68c7d24f53f5c8821164525844505a9b54db000b9176e557e9fc8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logRelease files / zarr_cm_tree-0.1.0-py3-none-any.whl
| Download URL | zarr_cm_tree-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9629dc5e2a7513fdfd59bd150843af21cc2382eb777a42cf06a4fdab8880ff57
|
|
BLAKE2b-256 checksum How to use checksums |
092fa309decd11311d28d7671a0db964bcfb39fa889bb63ea76dbbbf1853ccc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency log