docs: add spec-style description of the consolidated metadata format - #4283
docs: add spec-style description of the consolidated metadata format#4283d-v-b wants to merge 6 commits into
Conversation
Add a new user-guide page that describes exactly what zarr-python reads and writes for consolidated metadata in Zarr formats 2 and 3, so that other implementations can interoperate. Quotes and attributes the schema text from zarr-specs#309 (Tom Augspurger, CC-BY-4.0), documents the key ordering, the empty child-group marker, the v2 `.zmetadata` layout and its deviation from zarr-python 2.x, and the reader/writer procedures. Also correct the 3.1.1 sort-order note on the existing page, which said "lexicographic" while the implementation uses NFKC-casefolded ordering. Assisted-by: ClaudeCode:claude-fable-5
|
@TomAugspurger you should probably also have a look, since this is an LLM summarizing your work |
Congrats! I'll take a look when I get a chance. Do you have any more info on the motivation for this document. I gather it's primarily for other implementations looking to interoperate with what we write, and am trying to balance this approach vs. telling them to read the spec + source code :) |
|
I asked for a spec on Zulip and Davis was kind enough to create one. The motivation is that we picked up the consolidated metadata in the newly-formed Zarr Format Working Group and I wanted to get a better understanding of the current zarr-python implementation. Having a spec here would be great, but even better would be if we could eventually bring this document into the Zarr 3 spec. |
IMO we don't really have a place for a consolidated metadata spec in the |
Right. With @joshmoore, I am working on a proposal for the ZFWG governance and I could imagine using consolidated metadata as testcase for the governance process. |
TomAugspurger
left a comment
There was a problem hiding this comment.
Thanks for the context. With that in mind, I'll view this as a somewhat temporary document. Though just merging the zarr-specs PR feels infinitely better.
And for those interested in the implementation, rereading the discussion in #2113 might also be fruitful.
| Consolidated metadata essentially stores all the metadata for a hierarchy in the | ||
| metadata of the root Group. | ||
|
|
||
| This page describes how to use consolidated metadata from Python. For a precise |
There was a problem hiding this comment.
I have some hesitancy about linking to this document from user-facing docs. I think the spec (or the PR for the spec) should be sufficient for users, and if it isn't then the docs should be improved there.
| of strings joined by `"/"`. For keys with the same depth, the tie is broken by | ||
| comparing the paths after Unicode NFKC normalization and case-folding. This | ||
| behavior ensures deterministic metadata output for a given group. |
There was a problem hiding this comment.
This seems worse for causal readers.
Let's at least keep "lexicographic" (since it isn't incorrect, right?) And if we want to be more specific we can, but let's link to the Python docs on normalization.
|
|
||
| ## Concepts | ||
|
|
||
| A hierarchy is **consolidated at** a group (the *consolidating group*). The |
There was a problem hiding this comment.
"consolidating group" isn't a term in zarr-developers/zarr-specs#309. If we want to make it one, let's propose it there.
| (`GroupMetadata.consolidated_metadata.metadata`). It is never written to a | ||
| store and is mentioned here only because it leaks into the on-disk form in | ||
| one place (the [empty child marker](#child-groups-carry-an-empty-marker)). | ||
|
|
There was a problem hiding this comment.
I don't think "leaks into" is accurate here, or it conveys the wrong impression. That's deliberate, saying that there aren't any children.
|
|
||
| ## Paths | ||
|
|
||
| A **path** is the name of a node relative to the consolidating group: |
There was a problem hiding this comment.
IIRC paths are already defined in the spec. Link to that.
| at `B` produces `C`, `y`; consolidating at `C` produces no paths (an empty | ||
| mapping, which is still written). | ||
|
|
||
| !!! note "Difference from the zarr-specs#309 text" |
There was a problem hiding this comment.
Ha, I had a review pending from April 2025 pointing out this issue. Submitted that: zarr-developers/zarr-specs#309 (comment) and we can fix it in the spec.
| Each value is a complete node metadata document, i.e. exactly what would be | ||
| found in that node's own `zarr.json`, with the following rules: | ||
|
|
||
| * The document MUST contain `zarr_format`. Readers discriminate on this first; |
There was a problem hiding this comment.
I'm guessing this isn't intended / well-tested.
| This is the one place the nested in-memory form shows through. The marker | ||
| does **not** mean the child group has no children: the child's descendants are | ||
| still listed in the flat mapping at the consolidating group. It exists so |
There was a problem hiding this comment.
This is wrong (or I'm misunderstanding something). But AFAIK the presence of metadata: {} definitely does indicate a group with no children.
Co-authored-by: Tom Augspurger <tom.augspurger88@gmail.com>
Co-authored-by: Tom Augspurger <tom.augspurger88@gmail.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4283 +/- ##
=======================================
Coverage 94.21% 94.21%
=======================================
Files 92 92
Lines 12861 12861
=======================================
Hits 12117 12117
Misses 744 744 🚀 New features to boost your workflow:
|
Summary
This is a claude-authored contribution that adds specification-style documentation for how zarr-python implements consolidated metadata. I'm pretty busy these days with a newborn baby so I can't give this careful review. I am opening this as a draft and leaving it to other folks to push it forward.
cc @normanrz
🤖 AI text below 🤖
Add a new user-guide page that describes exactly what zarr-python reads and writes for consolidated metadata in Zarr formats 2 and 3, so that other implementations can interoperate. Quotes and attributes the schema text from zarr-specs#309 (Tom Augspurger, CC-BY-4.0), documents the key ordering, the empty child-group marker, the v2
.zmetadatalayout and its deviation from zarr-python 2.x, and the reader/writer procedures.Also correct the 3.1.1 sort-order note on the existing page, which said "lexicographic" while the implementation uses NFKC-casefolded ordering.
Assisted-by: ClaudeCode:claude-fable-5
Author attestation
TODO
docs/user-guide/*.mdchanges/