xzarrguard
xzarrguard solves the ambiguity of interpreting missing chunk files as NaN, and provides concise APIs and a CLI to validate completeness of Zarr v3 stores, create local stores with explicit no-data policy, and convert between manifest/materialized no-data representations.
Install
PyPI: pip install xzarrguard
PyPI + S3 support: pip install "xzarrguard[s3]"
conda: conda install xzarrguard
from source: pip install .
Install-free CLI usage
uv: uvx xzarrguard check /path/to/store.zarr
pixi: pixi exec xzarrguard check /path/to/store.zarr
Remote check uses fsspec backends. For S3-compatible stores:
xzarrguard check "s3://example-bucket/path/to/store.zarr" \
--profile example-profile \
--endpoint-url "https://object-store.example.com"
API quickstart
from xzarrguard import check_store, create_store
report = check_store("store.zarr")
if report:
print("store is complete")
remote_report = check_store(
"s3://example-bucket/path/to/store.zarr",
storage_options={
"profile": "example-profile",
"client_kwargs": {"endpoint_url": "https://object-store.example.com"},
},
)
create_store(
dataset,
"store.zarr",
no_data_chunks={"temperature": [(0, 0)]},
no_data_strategy="manifest",
)
Write and guard in one step (wrapper around .to_zarr()):
from xzarrguard import guarded_to_zarr
guarded_to_zarr(dataset, "store.zarr")
Recommended distributed-write workflow:
- Use upstream
xarray.Dataset.to_zarr(..., write_empty_chunks=True)during the distributed write phase so workers materialize chunk keys deterministically. - Finalize with
xzarrguardconversion to derive compact manifests from no-data chunks.
from xzarrguard import convert_store
convert_store("store.zarr", direction="auto")
In-place metadata-only guard update (no chunk rewrite):
create_store(
None,
"store.zarr",
no_data_chunks={"temperature": [(0, 0)]},
in_place_metadata_only=True,
)
Treat the current store as baseline and derive allowed-missing chunks from what is currently missing:
create_store(
None,
"store.zarr",
in_place_metadata_only=True,
infer_no_data_from_store=True,
)
CLI quickstart
xzarrguard check store.zarr
xzarrguard check "s3://example-bucket/path/to/store.zarr" --profile example-profile --endpoint-url "https://object-store.example.com"
xzarrguard create source.zarr target.zarr --no-data no_data.json
xzarrguard create store.zarr --in-place-metadata-only --no-data no_data.json
xzarrguard create store.zarr --in-place-metadata-only --infer-no-data-from-store
xzarrguard convert store.zarr
xzarrguard convert store.zarr --direction manifest_to_materialized
Note: you may see ZarrUserWarning: Object at .xzarrguard is not recognized as a component of a Zarr hierarchy. when tooling walks the store hierarchy. This is expected: .xzarrguard/ is xzarrguard sidecar metadata, not a Zarr array/group node.
Coverage
pytest
pytest prints terminal coverage and writes coverage.xml.
Documentation
https://j-haacker.github.io/xzarrguard/
zensical serve
zensical build --clean
Channels
- PyPI: https://pypi.org/project/xzarrguard/
- Conda-forge: https://anaconda.org/conda-forge/xzarrguard
- GitHub: https://github.com/j-haacker/xzarrguard
Release (maintainers)
# bump src/xzarrguard/_version.py first
python -m build
python -m twine check dist/*
python -m twine upload dist/*
Use a PyPI API token for upload (for example TWINE_USERNAME=__token__).
For conda-forge, update recipe/recipe.yaml after the PyPI release (fixed version + PyPI sdist URL + sha256), then submit a recipe/feedstock PR.
Acknowledgement: Initial scaffolding and implementation assistance by OpenAI Codex.
Metadata
Release files for xzarrguard 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| xzarrguard-0.1.2.tar.gz | 26.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xzarrguard-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.1 kB
Release files / xzarrguard-0.1.2.tar.gz
| Download URL | xzarrguard-0.1.2.tar.gz |
|---|---|
| Size | 26.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
68e9c07e9c78d077367daa96f121dee6ed26a06080b36e040740c2e5cd63d6f5
|
|
BLAKE2b-256 checksum How to use checksums |
3826bb492d117bdb21f0621dd6f8684d8e9d67d3a91022be880f7e433c6309eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 6, 2026.
Transparency logRelease files / xzarrguard-0.1.2-py3-none-any.whl
| Download URL | xzarrguard-0.1.2-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
36e08da48d9adf6fa1c18890e8cedd2c963bc3e402dc9e3ad6c3d31b6ce399a7
|
|
BLAKE2b-256 checksum How to use checksums |
c90034dfab43bb2d8d985f93587f53e3d6d06f0a0dd4899f7a76f5f90de37690
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 6, 2026.
Transparency log