From 8da13336dfa60c2b4412097bc5e58488aebbb66c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 19:28:07 +0200 Subject: [PATCH 01/13] chore(deps): bump the actions group across 1 directory with 8 updates (#176) Bumps the actions group with 8 updates in the / directory: | Package | From | To | | --- | --- | --- | | [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) | `0.9.5` | `0.9.6` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6.0.0` | `6.0.1` | | [github/issue-metrics](https://github.com/github/issue-metrics) | `4.2.2` | `4.2.7` | | [j178/prek-action](https://github.com/j178/prek-action) | `2.0.3` | `2.0.4` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `7.0.0` | `8.0.1` | | [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.13.0` | `1.14.0` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.3` | `0.5.6` | Updates `prefix-dev/setup-pixi` from 0.9.5 to 0.9.6 - [Release notes](https://github.com/prefix-dev/setup-pixi/releases) - [Commits](https://github.com/prefix-dev/setup-pixi/compare/1b2de7f3351f171c8b4dfeb558c639cb58ed4ec0...5185adfbffb4bd703da3010310260805d89ebb11) Updates `codecov/codecov-action` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/57e3a136b779b570ffcdbf80b3bdc90e7fab3de2...e79a6962e0d4c0c17b229090214935d2e33f8354) Updates `github/issue-metrics` from 4.2.2 to 4.2.7 - [Release notes](https://github.com/github/issue-metrics/releases) - [Commits](https://github.com/github/issue-metrics/compare/c9e9838147fd355dace335ba787f01b6641a400a...1e38d5e62363e14db8019ed7d106b9855bdba6cc) Updates `j178/prek-action` from 2.0.3 to 2.0.4 - [Release notes](https://github.com/j178/prek-action/releases) - [Commits](https://github.com/j178/prek-action/compare/6ad80277337ad479fe43bd70701c3f7f8aa74db3...bdca6f102f98e2b4c7029491a53dfd366469e33d) Updates `actions/upload-artifact` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v7...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) Updates `actions/download-artifact` from 7.0.0 to 8.0.1 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) Updates `pypa/gh-action-pypi-publish` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.13.0...cef221092ed1bacb1cc03d23a2d87d1d172e277b) Updates `zizmorcore/zizmor-action` from 0.5.3 to 0.5.6 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/b1d7e1fb5de872772f31590499237e7cce841e8e...5f14fd08f7cf1cb1609c1e344975f152c7ee938d) --- updated-dependencies: - dependency-name: prefix-dev/setup-pixi dependency-version: 0.9.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: codecov/codecov-action dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: github/issue-metrics dependency-version: 4.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: j178/prek-action dependency-version: 2.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/downstream.yml | 2 +- .github/workflows/gpu_test.yml | 2 +- .github/workflows/hypothesis.yaml | 2 +- .github/workflows/issue-metrics.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 4 ++-- .github/workflows/zarr-metadata-release.yml | 12 ++++++------ .github/workflows/zizmor.yml | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml index 74026233c4..3eb6898895 100644 --- a/.github/workflows/downstream.yml +++ b/.github/workflows/downstream.yml @@ -34,7 +34,7 @@ jobs: persist-credentials: false - name: Set up pixi - uses: prefix-dev/setup-pixi@1b2de7f3351f171c8b4dfeb558c639cb58ed4ec0 # v0.9.5 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: manifest-path: xarray/pixi.toml diff --git a/.github/workflows/gpu_test.yml b/.github/workflows/gpu_test.yml index 403441b306..333769cb9e 100644 --- a/.github/workflows/gpu_test.yml +++ b/.github/workflows/gpu_test.yml @@ -76,7 +76,7 @@ jobs: hatch env run --env "$HATCH_ENV" run-coverage - name: Upload coverage - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: gpu diff --git a/.github/workflows/hypothesis.yaml b/.github/workflows/hypothesis.yaml index 4f9467be7d..a456b2aa0a 100644 --- a/.github/workflows/hypothesis.yaml +++ b/.github/workflows/hypothesis.yaml @@ -93,7 +93,7 @@ jobs: key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }} - name: Upload coverage - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: tests diff --git a/.github/workflows/issue-metrics.yml b/.github/workflows/issue-metrics.yml index 14fba5b9ec..510849ef3e 100644 --- a/.github/workflows/issue-metrics.yml +++ b/.github/workflows/issue-metrics.yml @@ -33,7 +33,7 @@ jobs: echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV" - name: Run issue-metrics tool - uses: github/issue-metrics@c9e9838147fd355dace335ba787f01b6641a400a # v4.2.2 + uses: github/issue-metrics@1e38d5e62363e14db8019ed7d106b9855bdba6cc # v4.2.7 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} SEARCH_QUERY: 'repo:zarr-developers/zarr-python is:issue created:${{ env.last_month }} -reason:"not planned"' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 768e660ec2..fec211b4dd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -30,4 +30,4 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: enable-cache: true - - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3 + - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 03143d3e5b..62e571856b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,7 +78,7 @@ jobs: hatch env run --env "$HATCH_ENV" run-coverage - name: Upload coverage if: ${{ matrix.dependency-set == 'optional' && matrix.os == 'ubuntu-latest' }} - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: tests @@ -125,7 +125,7 @@ jobs: run: | hatch env run --env "$HATCH_ENV" run-coverage - name: Upload coverage - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: tests diff --git a/.github/workflows/zarr-metadata-release.yml b/.github/workflows/zarr-metadata-release.yml index 809d502f16..9639fcfdd3 100644 --- a/.github/workflows/zarr-metadata-release.yml +++ b/.github/workflows/zarr-metadata-release.yml @@ -35,7 +35,7 @@ jobs: - name: Build run: hatch build - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: zarr-metadata-dist path: packages/zarr-metadata/dist @@ -45,7 +45,7 @@ jobs: needs: [build] runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: zarr-metadata-dist path: dist @@ -76,7 +76,7 @@ jobs: id-token: write # required for OIDC trusted publishing attestations: write # required for artifact attestations steps: - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: zarr-metadata-dist path: dist @@ -87,7 +87,7 @@ jobs: subject-path: dist/* - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 upload_testpypi: name: Upload to TestPyPI @@ -101,7 +101,7 @@ jobs: id-token: write attestations: write steps: - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: zarr-metadata-dist path: dist @@ -112,6 +112,6 @@ jobs: subject-path: dist/* - name: Publish package to TestPyPI - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 with: repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index da19f22421..7ac4fe5d0e 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -32,4 +32,4 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 From 878a015b67ff82be0462fd234672734fb3ff29cd Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Wed, 8 Jul 2026 14:46:40 +0200 Subject: [PATCH 02/13] docs: fix errors and improve consistency across the documentation A full review of the documentation, verified by executing every runnable snippet against the current source. Highlights: Correctness: - performance.md: fix three claims contradicted by the page's own rendered output (memory-order/compression, inverted write_empty_chunks conclusion, wrong async.concurrency and threading.max_workers defaults); update stale MemoryStore pickle claim - Make three invisible exec blocks visible (rectilinear enable snippet in arrays.md, two config snippets in performance.md) - storage.md: fix the explicit-S3-filesystem example (endpoint_url misuse, missing bucket path) - config.md: show true defaults (earlier example no longer leaks array.order into the session); fix codecs.bytes key - arrays.md: document all five ArrayConfig options; correct memory:// store description; fix wrong column-index comments; remove orphaned example - v3_migration.md: remove Group.move and dimension_separator from not-yet-ported lists (both work); fix truncated store table row; update lapsed 2.x support-window and stale work-in-progress framing - cli.md: document the required cli extra; fix dry-run output; name the equivalent functions in zarr.metadata.migrate_v3 - installation.md: correct typing_extensions minimum; document all optional dependency groups (remote, gpu, cli, optional, cast-value-rs) - gpu.md: fix nonexistent zarr.Config.enable_gpu; add installation guidance - contributing.md: fix docs build output dir and serve URL; drop outdated doctest note - extending.md: custom data types are supported now, not future work - data_types.md: remove stray doctest output from a source block; use public zarr.dtype import; drop dead warnings-suppression boilerplate - quick-start.md: fix result="html" on a Python-repr output block Usability: - Reorder the user-guide nav into a beginner-to-advanced progression - quick-start.md: add H1 and heading hierarchy, remote-storage install note, and a Next steps section - user-guide/index.md: list the CLI, experimental, and examples pages - groups.md: explain group/create_group/open_group; document member enumeration and deletion - attributes.md: document bulk updates via update_attributes and deletion - consolidated_metadata.md: document the public use_consolidated knob - glossary.md: add Group, Attributes, and Consolidated Metadata entries; cover v2 metadata documents - Add cross-links between related pages throughout; replace "Coming soon" stubs with links to existing content - experimental.md: nest CacheStore sections properly; link the experimental API policy - release-notes.md: normalize version headings and dates Co-Authored-By: Claude Fable 5 --- docs/contributing.md | 8 +-- docs/index.md | 6 +- docs/quick-start.md | 37 +++++++--- docs/release-notes.md | 10 +-- docs/user-guide/arrays.md | 63 +++++++---------- docs/user-guide/attributes.md | 28 +++++++- docs/user-guide/cli.md | 24 +++++-- docs/user-guide/config.md | 16 +++-- docs/user-guide/consolidated_metadata.md | 30 ++++++-- docs/user-guide/data_types.md | 35 +++++----- .../examples/rectilinear_chunks.ipynb | 8 --- docs/user-guide/experimental.md | 45 ++++++------ docs/user-guide/extending.md | 18 +++-- docs/user-guide/glossary.md | 35 ++++++++-- docs/user-guide/gpu.md | 42 +++++++++-- docs/user-guide/groups.md | 52 ++++++++++++-- docs/user-guide/index.md | 13 +++- docs/user-guide/installation.md | 16 +++-- docs/user-guide/performance.md | 69 ++++++++++--------- docs/user-guide/storage.md | 23 ++++--- docs/user-guide/v3_migration.md | 36 +++++----- examples/custom_dtype/README.md | 11 ++- mkdocs.yml | 6 +- 23 files changed, 407 insertions(+), 224 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index 750f7c7a65..fbaed2a5ac 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -20,7 +20,7 @@ g = zarr.group() 2. An explanation of why the current behaviour is wrong/not desired, and what you expect instead. -3. Information about the version of Zarr, along with versions of dependencies and the Python interpreter, and installation information. The version of Zarr can be obtained from the `zarr.__version__` property. Please also state how Zarr was installed, e.g., "installed via pip into a virtual environment", or "installed using conda". Information about other packages installed can be obtained by executing `pip freeze` (if using pip to install packages) or `conda env export` (if using conda to install packages) from the operating system command prompt. The version of the Python interpreter can be obtained by running a Python interactive session, e.g.: +3. Information about the version of Zarr, along with versions of dependencies and the Python interpreter, and installation information. The version of Zarr can be obtained from the `zarr.__version__` attribute. Please also state how Zarr was installed, e.g., "installed via pip into a virtual environment", or "installed using conda". Information about other packages installed can be obtained by executing `pip freeze` (if using pip to install packages) or `conda env export` (if using conda to install packages) from the operating system command prompt. The version of the Python interpreter can be obtained by running a Python interactive session, e.g.: ```console python @@ -133,8 +133,6 @@ hatch env run --env test.py3.12-optional run All tests are automatically run via GitHub Actions for every pull request and must pass before code can be accepted. Test coverage is also collected automatically via the Codecov service. -> **Note:** Previous versions of Zarr-Python made extensive use of doctests. These tests were not maintained during the 3.0 refactor but may be brought back in the future. See issue #2614 for more details. - ### Code standards - using prek All code must conform to the PEP8 standard. Regarding line length, lines up to 100 characters are allowed, although please try to keep under 90 wherever possible. @@ -215,9 +213,9 @@ The documentation can be built locally by running: hatch --env docs run build ``` -The resulting built documentation will be available in the `docs/_build/html` folder. +The resulting built documentation will be available in the `site` folder. -Hatch can also be used to serve continuously updating version of the documentation during development at [http://0.0.0.0:8000/](http://0.0.0.0:8000/). This can be done by running: +Hatch can also be used to serve continuously updating version of the documentation during development at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). This can be done by running: ```bash hatch --env docs run serve diff --git a/docs/index.md b/docs/index.md index b8c2b07ee7..1ec5e93c75 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ pip install zarr or `conda`: ```bash -conda install --channel conda-forge zarr +conda install -c conda-forge zarr ``` ## Navigating the documentation @@ -45,14 +45,14 @@ conda install --channel conda-forge zarr introduction to Zarr's main concepts and links to additional tutorials. -- [:material-book-open:{ .lg .middle } __User guide__](user-guide/installation.md) +- [:material-book-open:{ .lg .middle } __User guide__](user-guide/index.md) --- A detailed guide for how to use Zarr-Python. -- [:material-api:{ .lg .middle } __API Reference__](api/zarr/open.md) +- [:material-api:{ .lg .middle } __API Reference__](api/zarr/index.md) --- diff --git a/docs/quick-start.md b/docs/quick-start.md index 0bad4f2e34..29232d2a04 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -1,7 +1,11 @@ -This section will help you get up and running with +# Quick start + +This page will help you get up and running with the Zarr library in Python to efficiently manage and analyze multi-dimensional arrays. +Zarr must be installed first -- see the [installation guide](user-guide/installation.md) +if you have not installed it yet. -### Creating an Array +## Creating an Array To get started, you can create a simple Zarr array: @@ -42,12 +46,12 @@ Here, we created a 2D array of shape `(100, 100)`, chunked into blocks of `(10, 10)`, and filled it with random floating-point data. This array was written to a `LocalStore` in the `data/example-1.zarr` directory. -#### Compression and Filters +### Compression and Filters Zarr supports data compression and filters. For example, to use Blosc compression: -```python exec="true" session="quickstart" source="above" result="code" +```python exec="true" session="quickstart" source="above" result="ansi" # Create a 2D Zarr array with Blosc compression z = zarr.create_array( @@ -70,7 +74,7 @@ print(z.info) This compresses the data using the Blosc codec with shuffle enabled for better compression. -### Hierarchical Groups +## Hierarchical Groups Zarr allows you to create hierarchical groups, similar to directories: @@ -94,12 +98,12 @@ print(root.tree()) This creates a group hierarchy with a group (`foo`) and two arrays (`bar` and `spam`). -#### Batch Hierarchy Creation +### Batch Hierarchy Creation Zarr provides tools for creating a collection of arrays and groups with a single function call. Suppose we want to copy existing groups and arrays into a new storage backend: -```python exec="true" session="quickstart" source="above" result="html" +```python exec="true" session="quickstart" source="above" result="code" # Create nested groups and add arrays root = zarr.group("data/example-4.zarr", attributes={'name': 'root'}) @@ -122,7 +126,7 @@ assert new_root.attrs == root.attrs Note that [`zarr.create_hierarchy`][] will only initialize arrays and groups -- copying array data must be done in a separate step. -### Persistent Storage +## Persistent Storage Zarr supports persistent storage to disk or cloud-compatible backends. While examples above utilized a [`zarr.storage.LocalStore`][], a number of other storage options are available. @@ -150,7 +154,7 @@ store.close() To open an existing array from a ZIP file: -```python exec="true" session="quickstart" source="above" result="code" +```python exec="true" session="quickstart" source="above" result="ansi" # Open the ZipStore in read-only mode store = zarr.storage.ZipStore("data/example-5.zip", read_only=True) @@ -163,7 +167,9 @@ print(z[:]) Zarr also integrates seamlessly with cloud object storage such as Amazon S3 and Google Cloud Storage using external libraries like [s3fs](https://s3fs.readthedocs.io) or -[gcsfs](https://gcsfs.readthedocs.io): +[gcsfs](https://gcsfs.readthedocs.io). Remote storage support requires the `remote` +optional dependencies (`pip install "zarr[remote]"`) as well as a filesystem library +for your storage service, such as `s3fs` for S3: ```python test="true" session="s3demo" markers="s3" source="above" import zarr @@ -175,4 +181,13 @@ z = zarr.create_array( z[:, :] = np.random.random((100, 100)) ``` -Read more about Zarr's storage options in the [User Guide](user-guide/index.md). +See the [Remote Store](user-guide/storage.md#remote-store) section of the storage guide +for more detail, including how to configure the underlying filesystem with `storage_options`. + +## Next steps + +This page only scratches the surface. Continue with the [User Guide](user-guide/index.md), in particular: + +- **[Arrays](user-guide/arrays.md)** - creating, reading, and writing arrays in depth +- **[Groups](user-guide/groups.md)** - organizing arrays into hierarchies +- **[Storage](user-guide/storage.md)** - the full range of local, remote, and in-memory storage options diff --git a/docs/release-notes.md b/docs/release-notes.md index 4511c9815e..d80d65505f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -114,9 +114,9 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr - [#3562](https://github.com/zarr-developers/zarr-python/issues/3562), [#3605](https://github.com/zarr-developers/zarr-python/issues/3605), [#3619](https://github.com/zarr-developers/zarr-python/issues/3619), [#3623](https://github.com/zarr-developers/zarr-python/issues/3623), [#3636](https://github.com/zarr-developers/zarr-python/issues/3636), [#3648](https://github.com/zarr-developers/zarr-python/issues/3648), [#3656](https://github.com/zarr-developers/zarr-python/issues/3656), [#3658](https://github.com/zarr-developers/zarr-python/issues/3658), [#3673](https://github.com/zarr-developers/zarr-python/issues/3673), [#3704](https://github.com/zarr-developers/zarr-python/issues/3704), [#3706](https://github.com/zarr-developers/zarr-python/issues/3706), [#3708](https://github.com/zarr-developers/zarr-python/issues/3708), [#3712](https://github.com/zarr-developers/zarr-python/issues/3712), [#3713](https://github.com/zarr-developers/zarr-python/issues/3713), [#3717](https://github.com/zarr-developers/zarr-python/issues/3717), [#3721](https://github.com/zarr-developers/zarr-python/issues/3721), [#3728](https://github.com/zarr-developers/zarr-python/issues/3728), [#3778](https://github.com/zarr-developers/zarr-python/issues/3778) -## zarr 3.1.5 (2025-11-21) +## 3.1.5 (2025-11-21) -## Bugfixes +### Bugfixes - Fix formatting errors in the release notes section of the docs. ([#3594](https://github.com/zarr-developers/zarr-python/issues/3594)) @@ -153,7 +153,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr - [#3515](https://github.com/zarr-developers/zarr-python/issues/3515), [#3532](https://github.com/zarr-developers/zarr-python/issues/3532), [#3533](https://github.com/zarr-developers/zarr-python/issues/3533), [#3553](https://github.com/zarr-developers/zarr-python/issues/3553) -## zarr 3.1.3 (2025-09-18) +## 3.1.3 (2025-09-18) ### Features @@ -576,7 +576,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr parameters of those instances. `ChunkKeyEncodingLike` should be used by high-level functions to provide a convenient way for creating `ChunkKeyEncoding` objects. ([#2763](https://github.com/zarr-developers/zarr-python/issues/2763)) -## 3.0.1 (Jan. 17, 2025) +## 3.0.1 (2025-01-17) * Implement `zarr.from_array` using concurrent streaming ([#2622](https://github.com/zarr-developers/zarr-python/issues/2622)). @@ -604,7 +604,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr * Speed up hypothesis tests ([#2650](https://github.com/zarr-developers/zarr-python/issues/2650)). * Remove multiple imports for an import name ([#2723](https://github.com/zarr-developers/zarr-python/issues/2723)). -## 3.0.0 (Jan. 9, 2025) +## 3.0.0 (2025-01-09) 3.0.0 is a new major release of Zarr-Python, with many breaking changes. See the [v3 migration guide](user-guide/v3_migration.md) for a listing of what's changed. diff --git a/docs/user-guide/arrays.md b/docs/user-guide/arrays.md index dd1788b7d2..f459b2d38d 100644 --- a/docs/user-guide/arrays.md +++ b/docs/user-guide/arrays.md @@ -8,8 +8,6 @@ Zarr has several functions for creating arrays. For example: import shutil shutil.rmtree('data', ignore_errors=True) import numpy as np - -np.random.seed(0) ``` ```python exec="true" session="arrays" source="above" result="ansi" @@ -21,10 +19,14 @@ print(z) The code above creates a 2-dimensional array of 32-bit integers with 10000 rows and 10000 columns, divided into chunks where each chunk has 1000 rows and 1000 columns (and so there will be 100 chunks in total). The data is written to an -in-memory store (see [`zarr.storage.MemoryStore`][] for more details). See -[Persistent arrays](#persistent-arrays) for details on storing arrays in other stores, -and see [Data types](data_types.md) for an in-depth look at the data types supported -by Zarr. +in-memory store: when `fsspec` is installed, a `memory://` URL resolves to a +[`zarr.storage.FsspecStore`][] backed by fsspec's in-memory filesystem; otherwise a +[`zarr.storage.ManagedMemoryStore`][] is used. See the [Storage guide](storage.md) +for more details on stores, and +[Persistent arrays](#persistent-arrays) for details on storing arrays in other stores. +See [Data types](data_types.md) for an in-depth look at the data types supported +by Zarr, and [Chunk size and shape](performance.md#chunk-size-and-shape) in the +performance guide for guidance on choosing chunk shapes. See the [creation API documentation](../api/zarr/create.md) for more detailed information about creating arrays. @@ -128,7 +130,7 @@ A Zarr array can be resized, which means that any of its dimensions can be increased or decreased in length. For example: ```python exec="true" session="arrays" source="above" result="ansi" -z = zarr.create_array(store='data/example-3.zarr', shape=(10000, 10000), dtype='int32',chunks=(1000, 1000)) +z = zarr.create_array(store='data/example-3.zarr', shape=(10000, 10000), dtype='int32', chunks=(1000, 1000)) z[:] = 42 print(f"Original shape: {z.shape}") z.resize((20000, 10000)) @@ -157,13 +159,15 @@ print(f"Shape after second append: {z.shape}") Zarr arrays are parametrized with a configuration that determines certain aspects of array behavior. -We currently support three configuration options for arrays: `write_empty_chunks`, `read_missing_chunks`, and `order`. +We currently support five configuration options for arrays: `order`, `write_empty_chunks`, `read_missing_chunks`, `sharding_coalesce_max_gap_bytes`, and `sharding_coalesce_max_bytes`. | field | type | default | description | | - | - | - | - | +| `order` | `Literal["C", "F"]` | `"C"` | The memory layout of arrays returned when reading data from the store. | `write_empty_chunks` | `bool` | `False` | Controls whether empty chunks are written to storage. See [Empty chunks](performance.md#empty-chunks). | `read_missing_chunks` | `bool` | `True` | Controls whether missing chunks are filled with the array's fill value on read. If `False`, reading missing chunks raises a [`ChunkNotFoundError`][zarr.errors.ChunkNotFoundError]. -| `order` | `Literal["C", "F"]` | `"C"` | The memory layout of arrays returned when reading data from the store. +| `sharding_coalesce_max_gap_bytes` | `int` | `1048576` (1 MiB) | When reading multiple chunks from the same shard, nearby byte ranges separated by no more than this many bytes are coalesced into a single request to the store. +| `sharding_coalesce_max_bytes` | `int` | `16777216` (16 MiB) | Requests will not be coalesced if doing so would exceed this byte size. !!! info The Zarr V3 spec states that readers should interpret an uninitialized chunk as containing the @@ -266,19 +270,6 @@ z = zarr.create_array(store='data/example-7.zarr', shape=data.shape, dtype=data. print(f"Compressors: {z.compressors}") ``` -To disable compression, set `compressors=None` when creating an array, e.g.: - -```python exec="true" session="arrays" source="above" result="ansi" -z = zarr.create_array( - store='data/example-8.zarr', - shape=(100000000,), - chunks=(1000000,), - dtype='int32', - compressors=None -) -print(f"Compressors: {z.compressors}") -``` - ## Filters In some cases, compression can be improved by transforming the data in some @@ -461,11 +452,11 @@ print(z.get_orthogonal_selection(([0, 2], slice(None)))) # select first and thi ``` ```python exec="true" session="arrays" source="above" result="ansi" -print(z.get_orthogonal_selection((slice(None), [1, 3]))) # select second and fourth columns) +print(z.get_orthogonal_selection((slice(None), [1, 3]))) # select second and fourth columns ``` ```python exec="true" session="arrays" source="above" result="ansi" -print(z.get_orthogonal_selection(([0, 2], [1, 3]))) # select rows [0, 2] and columns [1, 4] +print(z.get_orthogonal_selection(([0, 2], [1, 3]))) # select rows [0, 2] and columns [1, 3] ``` Data can also be modified, e.g.: @@ -489,7 +480,7 @@ print(z.oindex[:, [1, 3]]) # select second and fourth columns ``` ```python exec="true" session="arrays" source="above" result="ansi" -print(z.oindex[[0, 2], [1, 3]]) # select rows [0, 2] and columns [1, 4] +print(z.oindex[[0, 2], [1, 3]]) # select rows [0, 2] and columns [1, 3] ``` ```python exec="true" session="arrays" source="above" result="ansi" @@ -510,7 +501,7 @@ z[:] = data print(np.all(z.oindex[[0, 2], :] == z[[0, 2], :])) ``` -### Block Indexing +### Block indexing Zarr also supports block indexing, which allows selections of whole chunks based on their logical indices along each dimension of an array. For example, this allows selecting @@ -575,15 +566,6 @@ Any combination of integer and slice can be used for block indexing: print(z.blocks[2, 1:3]) ``` -```python exec="true" session="arrays" source="above" result="ansi" -root = zarr.create_group('data/example-19.zarr') -foo = root.create_array(name='foo', shape=(1000, 100), chunks=(10, 10), dtype='float32') -bar = root.create_array(name='bar', shape=(100,), dtype='int32') -foo[:, :] = np.random.random((1000, 100)) -bar[:] = np.arange(100) -print(root.tree()) -``` - ## Sharding Using small chunk shapes in very large arrays can lead to a very large number of chunks. @@ -596,7 +578,9 @@ This allows individual chunks to be read independently. However, when writing data, a full shard must be written in one go for optimal performance and to avoid concurrency issues. That means that shards are the units of writing and chunks are the units of reading. -Users need to configure the chunk and shard shapes accordingly. +Users need to configure the chunk and shard shapes accordingly. For guidance on +choosing chunk and shard shapes, see [Sharding](performance.md#sharding) in the +performance guide. Sharded arrays can be created by providing the `shards` parameter to [`zarr.create_array`][]. @@ -619,7 +603,7 @@ Without the `shards` argument, there would be 10,000 chunks stored as individual Because the feature is still stabilizing, it is disabled by default and must be explicitly enabled: - ```python exec="true" session="arrays-rectilinear" + ```python exec="true" session="arrays" source="above" import zarr zarr.config.set({"array.rectilinear_chunks": True}) ``` @@ -641,7 +625,6 @@ To create an array with rectilinear chunks, pass a nested list to the `chunks` parameter where each inner list gives the chunk sizes along one dimension: ```python exec="true" session="arrays" source="above" result="ansi" -zarr.config.set({"array.rectilinear_chunks": True}) z = zarr.create_array( store=zarr.storage.MemoryStore(), shape=(60, 100), @@ -775,9 +758,9 @@ pairs are accepted: When writing, Zarr automatically compresses repeated values into RLE format. -## Missing features in 3.0 +## Features not yet ported to Zarr-Python 3 -The following features have not been ported to 3.0 yet. +The following Zarr-Python 2 features are not yet available in Zarr-Python 3. ### Copying and migrating data diff --git a/docs/user-guide/attributes.md b/docs/user-guide/attributes.md index d5961ed38a..96a5d67584 100644 --- a/docs/user-guide/attributes.md +++ b/docs/user-guide/attributes.md @@ -32,5 +32,29 @@ print(z.attrs['baz']) print(z.attrs['qux']) ``` -Internally Zarr uses JSON to store array attributes, so attribute values must be -JSON serializable. +Attributes can be deleted with the `del` operator: + +```python exec="true" session="attributes" source="above" result="ansi" +del z.attrs['baz'] +print(sorted(z.attrs)) +``` + +Note that each attribute assignment or deletion writes the node's metadata +document back to the store. To change several attributes in a single write, +use [`zarr.Array.update_attributes`][] (or [`zarr.Group.update_attributes`][] +for groups), which merges the given dict into the existing attributes and +returns the updated array or group: + +```python exec="true" session="attributes" source="above" result="ansi" +z = z.update_attributes({'baz': 43, 'quux': True}) +print(sorted(z.attrs)) +``` + +Internally Zarr uses JSON to store array and group attributes, so attribute +values must be JSON serializable. + +When working with hierarchies that contain many arrays and groups, reading the +attributes of each node separately can be slow. See +[Consolidated metadata](consolidated_metadata.md) for a way to store the +metadata (including attributes) of all nodes in a hierarchy in a single +document. diff --git a/docs/user-guide/cli.md b/docs/user-guide/cli.md index 13fcb6f1b6..2d83ccbccd 100644 --- a/docs/user-guide/cli.md +++ b/docs/user-guide/cli.md @@ -2,9 +2,22 @@ Zarr-Python provides a command-line interface that enables: -- migration of Zarr v2 metadata to v3 +- migration of Zarr v2 metadata to v3 (see the [3.0 Migration Guide](v3_migration.md) for + migrating your *code* from the Zarr-Python 2 API to the Zarr-Python 3 API) - removal of v2 or v3 metadata +## Installation + +The command-line interface requires the `cli` optional dependencies. Install them with: + +```bash +pip install "zarr[cli]" +``` + +Without this extra, running `zarr` in a terminal will fail with `ModuleNotFoundError`. + +## Getting help + To see available commands run the following in a terminal: ```bash @@ -98,7 +111,7 @@ or modifying any files. zarr migrate v3 path/to/input.zarr --dry-run Dry run enabled - no new files will be created or changed. Log of files that would be created on a real run: -Saving metadata to path/to/input.zarr/zarr.json +Saving metadata to file://path/to/input.zarr/zarr.json ``` ## Verbose @@ -113,5 +126,8 @@ zarr --verbose remove-metadata v2 path/to/input.zarr ## Equivalent functions -All features of the command-line interface are also available via functions under -`zarr.metadata`. \ No newline at end of file +All features of the command-line interface are also available as functions in the +`zarr.metadata.migrate_v3` module: +[`migrate_v2_to_v3`][zarr.metadata.migrate_v3.migrate_v2_to_v3] and +[`remove_metadata`][zarr.metadata.migrate_v3.remove_metadata]. +See the [`zarr.metadata` API reference](../api/zarr/metadata.md) for details. diff --git a/docs/user-guide/config.md b/docs/user-guide/config.md index 71c021b070..d1a70a14b0 100644 --- a/docs/user-guide/config.md +++ b/docs/user-guide/config.md @@ -6,14 +6,22 @@ is based on the [donfig](https://github.com/pytroll/donfig) Python library. Configuration values can be set using code like the following: ```python exec="true" session="config" source="above" result="ansi" - import zarr +zarr.config.set({'array.order': 'F'}) + print(zarr.config.get('array.order')) ``` +`zarr.config.set` can also be used as a context manager, which restores the +previous configuration on exit, and `zarr.config.reset` restores the default +configuration: + ```python exec="true" session="config" source="above" result="ansi" -zarr.config.set({'array.order': 'F'}) +zarr.config.reset() + +with zarr.config.set({'array.order': 'F'}): + print(zarr.config.get('array.order')) print(zarr.config.get('array.order')) ``` @@ -34,13 +42,13 @@ Configuration options include the following: - Whether missing chunks are filled with the array's fill value on read `array.read_missing_chunks` (default `True`). Set to `False` to raise a [`ChunkNotFoundError`][zarr.errors.ChunkNotFoundError] instead. - Async and threading options, e.g. `async.concurrency` and `threading.max_workers` - Selections of implementations of codecs, codec pipelines and buffers -- Enabling GPU support with `zarr.config.enable_gpu()`. See GPU support for more. +- Enabling GPU support with `zarr.config.enable_gpu()`. See [GPU support](gpu.md) for more. - Control request merging when reading multiple chunks from the same shard with `array.sharding_coalesce_max_gap_bytes` and `array.sharding_coalesce_max_bytes`. Reads of nearby chunks are coalesced into a single request to the store when separated by at most `sharding_coalesce_max_gap_bytes` and the resulting merged read is no larger than `sharding_coalesce_max_bytes`. For selecting custom implementations of codecs, pipelines, buffers and ndbuffers, first register the implementations in the registry and then select them in the config. For example, an implementation of the bytes codec in a class `'custompackage.NewBytesCodec'`, -requires the value of `codecs.bytes.name` to be `'custompackage.NewBytesCodec'`. +requires the value of `codecs.bytes` to be `'custompackage.NewBytesCodec'`. This is the current default configuration: diff --git a/docs/user-guide/consolidated_metadata.md b/docs/user-guide/consolidated_metadata.md index d8066b6846..a887b2e313 100644 --- a/docs/user-guide/consolidated_metadata.md +++ b/docs/user-guide/consolidated_metadata.md @@ -5,7 +5,7 @@ stores. [zarr-specs#309](https://github.com/zarr-developers/zarr-specs/pull/309) has proposed a formal extension to the v3 specification to support consolidated metadata. -Zarr-Python implements the [Consolidated Metadata](https://github.com/zarr-developers/zarr-specs/pull/309) for v2 and v3 stores. +Zarr-Python implements the Consolidated Metadata feature for both the v2 and v3 formats. Consolidated metadata can reduce the time needed to load the metadata for an entire hierarchy, especially when the metadata is being served over a network. Consolidated metadata essentially stores all the metadata for a hierarchy in the @@ -48,8 +48,8 @@ result = zarr.consolidate_metadata("memory://consolidated-metadata-demo") print(result) ``` -If we open that group, the Group's metadata has a `zarr.core.group.ConsolidatedMetadata` -that can be used: +If we open that group, the Group's metadata includes a `ConsolidatedMetadata` object +holding the metadata for every child node, which can be used: ```python exec="true" session="consolidated_metadata" source="above" result="ansi" from pprint import pprint @@ -58,7 +58,6 @@ import io consolidated = zarr.open_group(store="memory://consolidated-metadata-demo") consolidated_metadata = consolidated.metadata.consolidated_metadata.metadata -# Note: pprint can be used without capturing the output regularly output = io.StringIO() pprint(dict(sorted(consolidated_metadata.items())), stream=output, width=60) print(output.getvalue()) @@ -74,7 +73,7 @@ With nested groups, the consolidated metadata is available on the children, recu ```python exec="true" session="consolidated_metadata" source="above" result="ansi" child = group.create_group('child', attributes={'kind': 'child'}) -grandchild = child.create_group('child', attributes={'kind': 'grandchild'}) +grandchild = child.create_group('grandchild', attributes={'kind': 'grandchild'}) consolidated = zarr.consolidate_metadata("memory://consolidated-metadata-demo") output = io.StringIO() @@ -89,6 +88,23 @@ print(output.getvalue()) order is used to break the tie. This behaviour ensures deterministic metadata output for a given group. +### Controlling the use of consolidated metadata + +By default, [`zarr.open_group`][] uses consolidated metadata if it is present, and +falls back to reading metadata from the store otherwise. This behaviour can be +controlled with the `use_consolidated` keyword. Pass `use_consolidated=False` to +ignore consolidated metadata and always read the metadata of child nodes directly +from the store: + +```python exec="true" session="consolidated_metadata" source="above" result="ansi" +group = zarr.open_group(store="memory://consolidated-metadata-demo", use_consolidated=False) +print(group.metadata.consolidated_metadata) +``` + +Passing `use_consolidated=True` instead raises an error if consolidated metadata is +not found, which is useful when reading over a network, where relying on many +per-node metadata requests would be slow. + ## Synchronization and Concurrency Consolidated metadata is intended for read-heavy use cases on slowly changing @@ -99,7 +115,9 @@ removed, or modified, consolidated metadata may not be desirable. would need to be re-consolidated to keep it in sync with the store. 2. Readers using consolidated metadata will regularly see a "past" version of the metadata, at the time they read the root node with its consolidated - metadata. + metadata. Readers who need the latest view of a changing hierarchy can pass + `use_consolidated=False` to [`zarr.open_group`][] to always read child + metadata directly from the store. ## Stores Without Support for Consolidated Metadata diff --git a/docs/user-guide/data_types.md b/docs/user-guide/data_types.md index 6f6bb05033..642a09d714 100644 --- a/docs/user-guide/data_types.md +++ b/docs/user-guide/data_types.md @@ -1,6 +1,6 @@ # Array data types -## Zarr's Data Type Model +## Zarr's data type model Zarr is designed for interoperability with NumPy, so if you are familiar with NumPy or any other N-dimensional array library, Zarr's model for array data types should seem familiar. However, Zarr @@ -14,7 +14,7 @@ which adds some unique aspects to the Zarr data type model. The following sections explain Zarr's data type model in greater detail and demonstrate the Zarr Python APIs for working with Zarr data types. -### Array Data Types +### Array data types Every Zarr array has a data type, which defines the meaning of the array's elements. An array's data type is encoded in the JSON metadata for the array. This means that the data type of an array must be @@ -38,10 +38,10 @@ For the boolean data type, the scalar encoding is simple—booleans are natively JSON, so Zarr saves booleans as JSON booleans. Other scalars, like floats or raw bytes, have more elaborate encoding schemes, and in some cases, this scheme depends on the Zarr format version. -## Data Types in Zarr Version 2 +## Data types in Zarr version 2 Version 2 of the Zarr format defined its data types relative to -[NumPy's data types](https://numpy.org/doc/2.1/reference/arrays.dtypes.html#data-type-objects-dtype), +[NumPy's data types](https://numpy.org/doc/stable/reference/arrays.dtypes.html#data-type-objects-dtype), and added a few non-NumPy data types as well. With one exception ([structured data types](#structured-data-type)), the Zarr V2 JSON identifier for a data type is just the NumPy `str` attribute of that data type: @@ -64,7 +64,7 @@ print(dtype_meta) !!! note The `<` character in the data type metadata encodes the - [endianness](https://numpy.org/doc/2.2/reference/generated/numpy.dtype.byteorder.html), + [endianness](https://numpy.org/doc/stable/reference/generated/numpy.dtype.byteorder.html), or "byte order," of the data type. As per the NumPy model, in Zarr version 2 each data type has an endianness where applicable. However, Zarr version 3 data types do not store endianness information. @@ -72,7 +72,7 @@ print(dtype_meta) There are two special cases to consider: ["structured" data types](#structured-data-type), and ["object"](#object-data-type) data types. -### Structured Data Type +### Structured data type NumPy allows the construction of a so-called "structured" data types comprised of ordered collections of named fields, where each field is itself a distinct NumPy data type. See the NumPy documentation @@ -101,7 +101,7 @@ dtype_meta = json.loads(store['.zarray'].to_bytes())["dtype"] print(dtype_meta) ``` -### Object Data Type +### Object data type The NumPy "object" type is essentially an array of references to arbitrary Python objects. It can model arrays of variable-length UTF-8 strings, arrays of variable-length byte strings, or @@ -129,7 +129,7 @@ Although this fact can be ignored for many simple numeric data types, any compre Zarr V2 data types must either reject the "object" data types or include the "object codec" identifier in the JSON form of the basic data type model. -## Data Types in Zarr Version 3 +## Data types in Zarr version 3 The NumPy-based Zarr V2 data type representation was effective for simple data types but struggled with more complex data types, like "object" and "structured" data types. To address these limitations, @@ -159,7 +159,7 @@ Zarr V3 introduced several key changes to how data types are represented: For more about data types in Zarr V3, see the [V3 specification](https://zarr-specs.readthedocs.io/en/latest/v3/data-types/index.html). -## Data Types in Zarr Python +## Data types in Zarr Python The two Zarr formats that Zarr Python supports specify data types in different ways: data types in Zarr version 2 are encoded as NumPy-compatible strings (or lists, in the case of structured data @@ -191,7 +191,7 @@ API for the following operations: The following section lists the data types built in to Zarr Python. With a few exceptions, Zarr Python supports nearly all of the data types in NumPy. If you need a data type that is not listed -here, it's possible to create it yourself: see [Adding New Data Types](#adding-new-data-types). +here, it's possible to create it yourself: see [Adding new data types](#adding-new-data-types). #### Boolean - [Boolean][zarr.dtype.Bool] @@ -260,14 +260,14 @@ here, it's possible to create it yourself: see [Adding New Data Types](#adding-n explicit `endian` parameter. If omitted, Zarr Python assumes little-endian for legacy compatibility but emits a warning. -### Example Usage +### Example usage This section will demonstrate the basic usage of Zarr data types. Create a `ZDType` from a native data type: ```python exec="true" session="data_types" source="above" -from zarr.core.dtype import Int8 +from zarr.dtype import Int8 import numpy as np int8 = Int8.from_native_dtype(np.dtype('int8')) ``` @@ -291,7 +291,6 @@ Serialize to JSON for Zarr V2: ```python exec="true" session="data_types" source="above" result="ansi" json_v2 = int8.to_json(zarr_format=2) print(json_v2) -{'name': '|i1', 'object_codec_id': None} ``` !!! note @@ -324,7 +323,7 @@ scalar_value = int8.from_json_scalar(42, zarr_format=3) assert scalar_value == np.int8(42) ``` -### Adding New Data Types +### Adding new data types Each Zarr data type is a separate Python class that inherits from [ZDType][zarr.dtype.ZDType]. You can define a custom data type by @@ -332,7 +331,7 @@ writing your own subclass of [ZDType][zarr.dtype.ZDType] and adding your data type to the data type registry. To see an executable demonstration of this process, see the [`custom_dtype` example](../user-guide/examples/custom_dtype.md). -### Data Type Resolution +### Data type resolution Although Zarr Python uses a different data type model from NumPy, you can still define a Zarr array with a NumPy data type object: @@ -375,16 +374,14 @@ For simple data types like `int`, the solution could be extremely simple: just maintain a lookup table that maps a NumPy data type to the Zarr data type equivalent. But not all data types are so simple. Consider this case: -```python exec="true" session="data_types" source="above" +```python exec="true" session="data_types" source="above" result="ansi" from zarr import create_array -import warnings import numpy as np -warnings.simplefilter("ignore", category=FutureWarning) a = create_array({}, shape=(10,), dtype=[('a', 'f8'), ('b', 'i8')]) print(a.dtype) # this is the NumPy data type ``` -```python exec="true" session="data_types" source="above" +```python exec="true" session="data_types" source="above" result="ansi" print(a.metadata.data_type) # this is the Zarr data type ``` diff --git a/docs/user-guide/examples/rectilinear_chunks.ipynb b/docs/user-guide/examples/rectilinear_chunks.ipynb index a2dd636ee8..37d40a3b7c 100644 --- a/docs/user-guide/examples/rectilinear_chunks.ipynb +++ b/docs/user-guide/examples/rectilinear_chunks.ipynb @@ -394,14 +394,6 @@ "\n", "print(\"Round-trip chunk sizes:\", roundtrip.chunks)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e8d42341-c242-44f5-ad6a-491370e3ffab", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/docs/user-guide/experimental.md b/docs/user-guide/experimental.md index 1c6d952c7c..a50be394c2 100644 --- a/docs/user-guide/experimental.md +++ b/docs/user-guide/experimental.md @@ -1,6 +1,8 @@ # Experimental features -This section contains documentation for experimental Zarr Python features. The features described here are exciting and potentially useful, but also volatile -- we might change them at any time. Take this into account if you consider depending on these features. +This section contains documentation for experimental Zarr Python features. The features described here are exciting and potentially useful, but also volatile -- we might change them at any time. Take this into account if you consider depending on these features. See the +[experimental API policy](../contributing.md#experimental-api-policy) for the stability +guarantees (or lack thereof) that apply to everything documented on this page. ## `CacheStore` @@ -16,10 +18,11 @@ when the cache reaches its maximum size. Because the `CacheStore` uses an ordinary Zarr `Store` object as the caching layer, you can reuse the data stored in the cache later. -> **Note:** The CacheStore is a wrapper store that maintains compatibility with the full -> `zarr.abc.store.Store` API while adding transparent caching functionality. +!!! note + The CacheStore is a wrapper store that maintains compatibility with the full + `zarr.abc.store.Store` API while adding transparent caching functionality. -## Basic Usage +### Basic Usage Creating a CacheStore requires both a source store and a cache store. The cache store can be any Store implementation, providing flexibility in cache persistence: @@ -51,7 +54,7 @@ zarr_array[:] = np.random.random((100, 100)) The dual-store architecture allows you to use different store types for source and cache, such as a remote store for source data and a local store for persistent caching. -## Performance Benefits +### Performance Benefits The CacheStore provides significant performance improvements for repeated data access: @@ -79,20 +82,15 @@ print(f"Speedup is {speedup}") Cache effectiveness is particularly pronounced with repeated access to the same data chunks. -## Cache Configuration +### Cache Configuration The CacheStore can be configured with several parameters: -**max_size**: Controls the maximum size of cached data in bytes +**max_size**: Controls the maximum size of cached data in bytes. The +[Basic Usage](#basic-usage) example above sets a 256MB limit with +`max_size=256*1024*1024`: ```python exec="true" session="experimental" source="above" -# 256MB cache with size limit -cache = CacheStore( - store=source_store, - cache_store=cache_store, - max_size=256*1024*1024 -) - # Unlimited cache size (use with caution) cache = CacheStore( store=source_store, @@ -137,14 +135,15 @@ cache = CacheStore( ) ``` -## Cache Statistics +### Cache Statistics The CacheStore provides statistics to monitor cache performance and state: ```python exec="true" session="experimental" source="above" # Access some data to generate cache activity -data = zarr_array[0:50, 0:50] # First access - cache miss -data = zarr_array[0:50, 0:50] # Second access - cache hit +# (these chunks were already cached by the reads above, so both accesses are cache hits) +data = zarr_array[0:50, 0:50] +data = zarr_array[0:50, 0:50] # Get comprehensive cache information info = cached_store.cache_info() @@ -159,7 +158,7 @@ print(info['cache_set_data']) The `cache_info()` method returns a dictionary with detailed information about the cache state. -## Cache Management +### Cache Management The CacheStore provides methods for manual cache management: @@ -177,7 +176,7 @@ assert info['current_size'] == 0 The `clear_cache()` method is an async method that clears both the cache store (if it supports the `clear` method) and all internal tracking data. -## Best Practices +### Best Practices 1. **Choose appropriate cache store**: Use MemoryStore for fast temporary caching or LocalStore for persistent caching 2. **Size the cache appropriately**: Set `max_size` based on available storage and expected data access patterns @@ -186,12 +185,12 @@ The `clear_cache()` method is an async method that clears both the cache store 5. **Consider data locality**: Group related data accesses together to improve cache efficiency 6. **Set appropriate expiration**: Use `max_age_seconds` for time-sensitive data or "infinity" for static data -## Working with Different Store Types +### Working with Different Store Types The CacheStore can wrap any store that implements the `zarr.abc.store.Store` interface and use any store type for the cache backend: -### Local Store with Memory Cache +#### Local Store with Memory Cache ```python exec="true" session="experimental-memory-cache" source="above" from zarr.storage import LocalStore, MemoryStore @@ -208,7 +207,7 @@ cached_store = CacheStore( ) ``` -### Memory Store with Persistent Cache +#### Memory Store with Persistent Cache ```python exec="true" session="experimental-local-cache" source="above" from tempfile import mkdtemp @@ -228,7 +227,7 @@ cached_store = CacheStore( The dual-store architecture provides flexibility in choosing the best combination of source and cache stores for your specific use case. -## Examples from Real Usage +### Examples from Real Usage Here's a complete example demonstrating cache effectiveness: diff --git a/docs/user-guide/extending.md b/docs/user-guide/extending.md index cefeb114c5..8602ec8c3b 100644 --- a/docs/user-guide/extending.md +++ b/docs/user-guide/extending.md @@ -50,8 +50,8 @@ Custom codecs should also implement the following methods: To use custom codecs in Zarr, they need to be registered using the [entrypoint mechanism](https://packaging.python.org/en/latest/specifications/entry-points/). Commonly, entrypoints are declared in the `pyproject.toml` of your package under the -`[project.entry-points."zarr.codecs"]` section. Zarr will automatically discover and -load all codecs registered with the entrypoint mechanism from imported modules. +`[project.entry-points."zarr.codecs"]` section. Zarr will automatically discover +all codecs registered via the entrypoint mechanism in installed packages. ```toml [project.entry-points."zarr.codecs"] @@ -74,7 +74,8 @@ implementation. ## Custom stores -Coming soon. +Custom stores can be created by implementing the [`zarr.abc.store.Store`][] interface. +See [developing custom stores](storage.md#developing-custom-stores) for more information. ## Custom array buffers @@ -82,7 +83,16 @@ Zarr-python provides control over where and how arrays are stored in memory thro [`zarr.abc.buffer.Buffer`][]. Currently both CPU (the default) and GPU implementations are provided (see [Using GPUs with Zarr](gpu.md) for more information). You can implement your own buffer classes by implementing the interface defined in [`zarr.abc.buffer.BufferPrototype`][]. +Like codecs, custom buffer implementations can be registered via entrypoints, using the +`zarr.buffer` and `zarr.ndbuffer` entrypoint groups. + +## Custom data types + +Zarr supports user-defined data types. See the +[data types documentation](data_types.md) for an explanation of how Zarr Python +models data types and how to write your own, and the +[custom data type example](examples/custom_dtype.md) for a complete worked example. ## Other extensions -In the future, Zarr will support writing custom data types and chunk grids. +In the future, Zarr will support writing custom chunk grids. diff --git a/docs/user-guide/glossary.md b/docs/user-guide/glossary.md index 3eb63925cc..dde08388a1 100644 --- a/docs/user-guide/glossary.md +++ b/docs/user-guide/glossary.md @@ -9,12 +9,18 @@ This page defines key terms used throughout the zarr-python documentation and AP An N-dimensional typed array stored in a Zarr [store](#store). An array's [metadata](#metadata) defines its shape, data type, chunk layout, and codecs. +### Group + +A container for [arrays](#array) and other groups, enabling hierarchical +organization of data — similar to directories in a file system, or groups in +HDF5. Like arrays, each group has its own [metadata](#metadata) and +[attributes](#attributes). See the [groups documentation](groups.md). + ### Chunk The fundamental unit of data in a Zarr array. An array is divided into chunks -along each dimension according to the [chunk grid](#chunk-grid), which is currently -part of Zarr's private API. Each chunk is independently compressed and encoded -through the array's [codec](#codec) pipeline. +along each dimension according to the [chunk grid](#chunk-grid). Each chunk is +independently compressed and encoded through the array's [codec](#codec) pipeline. When [sharding](#shard) is used, "chunk" refers to the inner chunks within each shard, because those are the compressible units. The chunks are the smallest units @@ -52,7 +58,8 @@ not the inner chunk boundaries. The inner chunk shape is defined within the grid. [`Array.chunks`][zarr.Array.chunks] returns the chunk shape for regular grids. For all grid types, `Array.read_chunk_sizes` and `Array.write_chunk_sizes` return the per-dimension chunk sizes in dask-style `tuple[tuple[int, ...], ...]` -format. +format. Note that while the chunk grid is a public concept of the Zarr format, +the classes zarr-python uses to model chunk grids are currently private API. ### Shard @@ -88,12 +95,28 @@ file) in the store, addressed by a key derived from its grid coordinates. ### Metadata -The JSON document (`zarr.json`) that describes an [array](#array) or group. For -arrays, metadata includes the shape, data type, [chunk grid](#chunk-grid), fill +The JSON document that describes an [array](#array) or [group](#group). In Zarr +format 3 this is a single `zarr.json` document; Zarr format 2 stores the +equivalent information in separate `.zarray`, `.zgroup`, and `.zattrs` documents. +For arrays, metadata includes the shape, data type, [chunk grid](#chunk-grid), fill value, and [codec](#codec) pipeline. Metadata is stored alongside the data in the [store](#store). Zarr-Python does not yet expose its internal metadata representation as part of its public API. +### Attributes + +User-defined key-value pairs (any JSON-serializable values) attached to an +[array](#array) or [group](#group). Attributes are stored in the +[metadata](#metadata) document. See the +[attributes documentation](attributes.md). + +### Consolidated Metadata + +A copy of the [metadata](#metadata) of every array and group in a hierarchy, +stored in the metadata of the root group so that the entire hierarchy can be +inspected with a single read from the [store](#store). See the +[consolidated metadata documentation](consolidated_metadata.md). + ## Codecs ### Codec diff --git a/docs/user-guide/gpu.md b/docs/user-guide/gpu.md index 6c26c3e564..26d1c114b0 100644 --- a/docs/user-guide/gpu.md +++ b/docs/user-guide/gpu.md @@ -1,6 +1,6 @@ # Using GPUs with Zarr -Zarr can use GPUs to accelerate your workload by running `zarr.Config.enable_gpu`. +Zarr can use GPUs to accelerate your workload by running `zarr.config.enable_gpu()`. !!! note `zarr-python` currently supports reading the ndarray data into device (GPU) @@ -11,20 +11,50 @@ Zarr can use GPUs to accelerate your workload by running `zarr.Config.enable_gpu the GPU, avoiding the need to move data between the host and device for compression and decompression. +## Installation + +Zarr's GPU support requires [CuPy](https://cupy.dev), which in turn requires a +CUDA-compatible NVIDIA GPU. CuPy can be installed alongside Zarr with the `gpu` +extra (see [Installation](installation.md) for the other optional dependency groups): + +```console +pip install "zarr[gpu]" +``` + +This installs the `cupy-cuda12x` package. If you need a CuPy build for a different +CUDA version, see the [CuPy installation guide](https://docs.cupy.dev/en/stable/install.html) +and install the appropriate package yourself. + ## Reading data into device memory -[`zarr.config`][] configures Zarr to use GPU memory for the data -buffers used internally by Zarr via `enable_gpu()`. +Calling `zarr.config.enable_gpu()` configures Zarr to use GPU memory for the data +buffers used internally by Zarr: ```python test="true" session="gpu-demo" markers="gpu" source="above" import zarr import cupy as cp + zarr.config.enable_gpu() z = zarr.create_array( store="memory://gpu-demo", shape=(100, 100), chunks=(10, 10), dtype="float32", ) -type(z[:10, :10]) -# cupy.ndarray +assert isinstance(z[:10, :10], cp.ndarray) +``` + +Note that the arrays returned by reads are of type `cupy.ndarray` rather than +NumPy arrays. + +`zarr.config.enable_gpu()` returns a [donfig](https://donfig.readthedocs.io/en/latest/) +`ConfigSet`, which can be used as a context manager to enable GPU support for a +limited scope: + +```python test="true" session="gpu-demo" markers="gpu" source="above" +with zarr.config.enable_gpu(): + data = z[:10, :10] +assert isinstance(data, cp.ndarray) ``` -Note that the output type is a `cupy.ndarray` rather than a NumPy array. +Under the hood, `enable_gpu()` selects the GPU-backed buffer classes +`zarr.buffer.gpu.Buffer` and `zarr.buffer.gpu.NDBuffer` via the `buffer` and +`ndbuffer` configuration keys. See [Custom array buffers](extending.md#custom-array-buffers) +for more on Zarr's buffer classes, including how to implement your own. diff --git a/docs/user-guide/groups.md b/docs/user-guide/groups.md index 5faa26a281..a2b40dfe8a 100644 --- a/docs/user-guide/groups.md +++ b/docs/user-guide/groups.md @@ -4,7 +4,7 @@ Zarr supports hierarchical organization of arrays via groups. As with arrays, groups can be stored in memory, on disk, or via other storage systems that support a similar interface. -To create a group, use the [`zarr.group`][] function: +To create a group, use the [`zarr.create_group`][] function: ```python exec="true" session="groups" source="above" result="ansi" import zarr @@ -12,6 +12,13 @@ root = zarr.create_group(store="memory://groups-demo") print(root) ``` +Zarr-Python provides three related functions for making groups: +[`zarr.create_group`][] creates a new group; [`zarr.open_group`][] creates or +re-opens a group depending on its `mode` argument (see below); and +[`zarr.group`][], which is kept for compatibility with Zarr-Python 2, is +equivalent to calling [`zarr.open_group`][] with `mode='a'` (or `mode='w'` +when `overwrite=True`). + Groups have a similar API to the Group class from [h5py](https://www.h5py.org/). For example, groups can contain other groups: ```python exec="true" session="groups" source="above" @@ -26,7 +33,8 @@ z1 = bar.create_array(name='baz', shape=(10000, 10000), chunks=(1000, 1000), dty print(z1) ``` -Members of a group can be accessed via the suffix notation, e.g.: +Members of a group can be accessed with square-bracket item access, like a +Python `dict`, e.g.: ```python exec="true" session="groups" source="above" result="ansi" print(root['foo']) @@ -66,10 +74,46 @@ print(z) For more information on groups see the [`zarr.Group` API docs](../api/zarr/group.md). -## Batch Group Creation +## Exploring group contents + +Groups also support a dict-like interface for enumerating their contents. The +[`zarr.Group.keys`][] method iterates over member names, and the `in` operator +tests for membership: + +```python exec="true" session="groups" source="above" result="ansi" +print(list(root.keys())) +print('foo' in root) +``` + +The [`zarr.Group.members`][] method returns `(name, member)` pairs for the +arrays and groups contained in a group: + +```python exec="true" session="groups" source="above" result="ansi" +for name, member in root.members(): + print(name, member) +``` + +By default only immediate members are returned. Pass `max_depth=None` to +recursively traverse the whole hierarchy below a group: + +```python exec="true" session="groups" source="above" result="ansi" +for name, member in root.members(max_depth=None): + print(name, member) +``` + +Members can be deleted with the `del` operator, which removes the member's +metadata and data from the store: + +```python exec="true" session="groups" source="above" result="ansi" +del root['foo/bar/baz'] +for name, member in root.members(max_depth=None): + print(name, member) +``` + +## Batch group creation You can also create multiple groups concurrently with a single function call. [`zarr.create_hierarchy`][] takes -a [`zarr Storage`](../api/zarr/storage.md) instance and a dict of `key : metadata` pairs, parses that dict, and +a [`Store`](../api/zarr/storage.md) instance and a dict of `key : metadata` pairs, parses that dict, and writes metadata documents to storage: ```python exec="true" session="groups" source="above" result="ansi" diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index ff6e354d80..6b4325c8fd 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -7,7 +7,7 @@ Welcome to the user guide, where you can learn more about using Zarr-Python! New to Zarr-Python? Start here: - **[Installation](installation.md)** - Install Zarr-Python -- **[Quick-start](../quick-start.md)** - Quick overview of core functionality +- **[Quick start](../quick-start.md)** - Quick overview of core functionality ## Core Concepts @@ -15,7 +15,7 @@ Learn the essential building blocks: - **[Arrays](arrays.md)** - Learn the fundamentals of working with arrays - **[Groups](groups.md)** - Organize your data with groups -- **[Attributes](attributes.md)** - Configure metadata to your data structures +- **[Attributes](attributes.md)** - Attach metadata to your arrays and groups - **[Storage](storage.md)** - Learn how data is stored and accessed ## Configuration & Setup @@ -23,6 +23,7 @@ Learn the essential building blocks: Customize your experience: - **[Runtime Configuration](config.md)** - Configure Zarr-Python for your needs +- **[Command-Line Interface](cli.md)** - Migrate and manage Zarr metadata from the terminal - **[V3 Migration](v3_migration.md)** - Upgrading from version 2 to version 3 ## Advanced Topics @@ -34,6 +35,14 @@ Take your skills to the next level: - **[GPU](gpu.md)** - Leverage GPU acceleration - **[Extending](extending.md)** - Extend functionality with custom code - **[Consolidated Metadata](consolidated_metadata.md)** - Advanced metadata management +- **[Experimental Features](experimental.md)** - Preview features that may change at any time + +## Examples + +Worked, end-to-end examples: + +- **[Custom Data Type](examples/custom_dtype.md)** - Extend Zarr-Python with a user-defined data type +- **[Rectilinear Chunk Grids](examples/rectilinear_chunks.ipynb)** - Use variable-sized chunks along each dimension ## Reference diff --git a/docs/user-guide/installation.md b/docs/user-guide/installation.md index c902acf171..4af7667a44 100644 --- a/docs/user-guide/installation.md +++ b/docs/user-guide/installation.md @@ -9,7 +9,7 @@ Required dependencies include: - [numpy](https://numpy.org) (2.0 or later) - [numcodecs](https://numcodecs.readthedocs.io) (0.14 or later) - [google-crc32c](https://github.com/googleapis/python-crc32c) (1.5 or later) -- [typing_extensions](https://typing-extensions.readthedocs.io) (4.9 or later) +- [typing_extensions](https://typing-extensions.readthedocs.io) (4.14 or later) - [donfig](https://donfig.readthedocs.io) (0.8 or later) ## pip @@ -23,10 +23,11 @@ pip install zarr There are a number of optional dependency groups you can install for extra functionality. These can be installed using `pip install "zarr[]"`, e.g. `pip install "zarr[gpu]"` -- `gpu`: support for GPUs -- `remote`: support for reading/writing to remote data stores - -Additional optional dependencies include `universal_pathlib`. These must be installed separately. +- `remote`: support for reading/writing to remote data stores (fsspec, obstore) +- `gpu`: support for GPUs (cupy) +- `cli`: support for the `zarr` [command-line interface](cli.md) (typer) +- `optional`: support for path-like access to local and remote stores (universal-pathlib) +- `cast-value-rs`: support for the `cast_value` codec (cast-value-rs) ## conda @@ -39,7 +40,7 @@ conda install -c conda-forge zarr Conda does not support optional dependencies, so you will have to manually install any packages needed to enable extra functionality. -# Nightly wheels +## Nightly wheels Development wheels are built nightly and published to the [scientific-python-nightly-wheels](https://anaconda.org/scientific-python-nightly-wheels) index. To install the latest nightly build: @@ -48,6 +49,7 @@ pip install --pre --extra-index-url https://pypi.anaconda.org/scientific-python- ``` Note that nightly wheels may be unstable and are intended for testing purposes. + ## Dependency support Zarr has endorsed [Scientific-Python SPEC 0](https://scientific-python.org/specs/spec-0000/) and now follows the version support window as outlined below: @@ -57,4 +59,4 @@ Zarr has endorsed [Scientific-Python SPEC 0](https://scientific-python.org/specs ## Development -To install the latest development version of Zarr, see the contributing guide. +To install the latest development version of Zarr, see the [contributing guide](../contributing.md). diff --git a/docs/user-guide/performance.md b/docs/user-guide/performance.md index 685ce7fe7e..818386578c 100644 --- a/docs/user-guide/performance.md +++ b/docs/user-guide/performance.md @@ -81,37 +81,38 @@ z6 = zarr.create_array(store={}, shape=(10000, 10000, 1000), shards=(1000, 1000, print(z6.info) ``` -`shards` can be `"auto"` as well, in which case the `array.target_shard_size_bytes` setting can be used to control the size of shards (i.e., the size of the chunks cumulatively and uncompressed within the shard will be as close to, without being bigger than, `array.target_shard_size_bytes`); otherwise, a default is used. +`shards` can be `"auto"` as well, in which case Zarr chooses a shard shape for you. +The `array.target_shard_size_bytes` configuration setting controls this choice: the +cumulative uncompressed size of the chunks within each shard will be as close as +possible to, without exceeding, that target. If the setting is `None` (the default), +Zarr falls back to a built-in heuristic for choosing the shard shape. ### Chunk memory layout -The order of bytes **within each chunk** of an array can be changed via the -`order` config option, to use either C or Fortran layout. For -multi-dimensional arrays, these two layouts may provide different compression -ratios, depending on the correlation structure within the data. E.g.: +The memory layout of the in-memory arrays that Zarr produces and consumes can be +changed via the `order` config option, to use either C or Fortran layout. This can +matter for performance when the data is passed to other libraries that expect a +particular memory layout. E.g.: ```python exec="true" session="performance" source="above" result="ansi" import numpy as np -a = np.arange(100000000, dtype='int32').reshape(10000, 10000).T -c = zarr.create_array(store={}, shape=a.shape, chunks=(1000, 1000), dtype=a.dtype, config={'order': 'C'}) -c[:] = a -print(c.info_complete()) +c = zarr.create_array(store={}, shape=(10000, 10000), chunks=(1000, 1000), dtype='int32', config={'order': 'C'}) +print(c[:100, :100].flags.c_contiguous) ``` ```python exec="true" session="performance" source="above" result="ansi" with zarr.config.set({'array.order': 'F'}): - f = zarr.create_array(store={}, shape=a.shape, chunks=(1000, 1000), dtype=a.dtype) - f[:] = a -print(f.info_complete()) - + f = zarr.create_array(store={}, shape=(10000, 10000), chunks=(1000, 1000), dtype='int32') +print(f[:100, :100].flags.f_contiguous) ``` -In the above example, Fortran order gives a better compression ratio. This is an -artificial example but illustrates the general point that changing the order of -bytes within chunks of an array may improve the compression ratio, depending on -the structure of the data, the compression algorithm used, and which compression -filters (e.g., byte-shuffle) have been applied. +Note that for Zarr format 3 arrays the `order` option only affects the in-memory +layout: the bytes written to storage are identical for both settings. The layout of +the serialized data is instead determined by the array's codecs (e.g. the transpose +codec), which can change how well the data compresses depending on the correlation +structure within the data and which compression filters (e.g., byte-shuffle) have +been applied. ### Subchunk memory layout @@ -142,7 +143,7 @@ assert arr.config.write_empty_chunks == False ``` The following example illustrates the effect of the `write_empty_chunks` flag on -the time required to write an array with different values.: +the time required to write an array with different values: ```python exec="true" session="performance" source="above" result="ansi" import zarr @@ -182,12 +183,17 @@ for write_empty_chunks in (True, False): print(f'\nwrite_empty_chunks={write_empty_chunks}:\n\tRandom Data: {full[0]:.4f}s, {full[1]} objects stored\n\t Empty Data: {empty[0]:.4f}s, {empty[1]} objects stored\n') ``` -In this example, writing random data is slightly slower with `write_empty_chunks=True`, -but writing empty data is substantially faster and generates far fewer objects in storage. +In this example, writing random data is slightly slower with `write_empty_chunks=False`, +because every chunk must be checked for emptiness before it is stored. Writing empty +data with `write_empty_chunks=False` is substantially faster, however, and stores no +objects at all. ### Changing chunk shapes (rechunking) -Coming soon. +Zarr-Python does not yet provide a built-in way to change the chunk shape of an +existing array in place. Arrays can, however, be resized and appended to along any +dimension — see [Resizing and appending](arrays.md#resizing-and-appending) — and data +can be copied to a new array created with the desired chunk shape. ## Parallel computing and synchronization @@ -204,7 +210,7 @@ determines the maximum number of concurrent I/O operations. The default value is 10, which is a conservative value. You may get improved performance by tuning the concurrency limit. You can adjust this value based on your specific needs: -```python exec="true" session="perf-concurrency" +```python exec="true" session="perf-concurrency" source="above" import zarr # Set concurrency for the current session @@ -234,7 +240,7 @@ By default it is `None`, which lets Python choose the pool size (typically You can set it explicitly when you want more predictable resource usage: -```python exec="true" session="perf-workers" +```python exec="true" session="perf-workers" source="above" import zarr zarr.config.set({'threading.max_workers': 8}) @@ -256,7 +262,7 @@ concurrently. total_concurrency ≈ dask_threads × zarr_async_concurrency ``` -For example, if you're running Dask with 10 threads and Zarr's default concurrency of 64, you could potentially have up to 640 concurrent operations, which may overwhelm your storage system or cause memory issues. +For example, if you're running Dask with 10 threads and Zarr's default concurrency of 10, you could potentially have up to 100 concurrent operations, which may overwhelm your storage system or cause memory issues. **Recommendation**: When using Dask with many threads, configure Zarr's concurrency settings: @@ -283,7 +289,7 @@ result = arr.mean(axis=0).compute() **Configuration guidelines for Dask workloads**: - `async.concurrency`: Controls the maximum number of concurrent async I/O operations. Start with a lower value (e.g., 4-8) when using many Dask threads. -- `threading.max_workers`: Controls Zarr's internal thread pool size for blocking operations (defaults to CPU count). Reduce this to avoid thread contention with Dask's scheduler. +- `threading.max_workers`: Controls Zarr's internal thread pool size for blocking operations (defaults to `None`, letting Python choose the pool size). Reduce this to avoid thread contention with Dask's scheduler. You may need to experiment with different values to find the optimal balance for your workload. Monitor your system's resource usage and adjust these settings based on whether your storage system or CPU is the bottleneck. @@ -300,14 +306,17 @@ When writing to the same chunks from multiple processes, you should use external ## Pickle support Zarr arrays and groups can be pickled, as long as the underlying store object can be -pickled. With the exception of the `zarr.storage.MemoryStore`, any of the -storage classes provided in the `zarr.storage` module can be pickled. +pickled. All of the storage classes provided in the `zarr.storage` module can be pickled. If an array or group is backed by a persistent store such as a `zarr.storage.LocalStore`, `zarr.storage.ZipStore` or `zarr.storage.FsspecStore` then the store data **are not** pickled. The only thing that is pickled is the necessary parameters to allow the store to re-open any underlying files or databases upon being unpickled. +Note that pickling a `zarr.storage.MemoryStore` copies the data it holds into the +pickle stream: unpickling produces an independent in-memory copy, so a `MemoryStore` +cannot be used to share data between processes. + E.g., pickle/unpickle a local store array: ```python exec="true" session="performance" source="above" result="ansi" @@ -320,7 +329,3 @@ z2 = pickle.loads(s) assert z1 == z2 print(np.all(z1[:] == z2[:])) ``` - -## Configuring Blosc - -Coming soon. diff --git a/docs/user-guide/storage.md b/docs/user-guide/storage.md index d5f840ab4b..d32fe217c9 100644 --- a/docs/user-guide/storage.md +++ b/docs/user-guide/storage.md @@ -18,13 +18,13 @@ being created automatically: ```python exec="true" session="storage" source="above" result="ansi" import zarr -# Implicitly create a writable LocalStore +# Implicitly creates a writable LocalStore group = zarr.create_group(store='data/foo/bar') print(group) ``` ```python exec="true" session="storage" source="above" result="ansi" -# Implicitly create a read-only FsspecStore +# Implicitly creates a read-only FsspecStore # Note: requires s3fs to be installed group = zarr.open_group( store='s3://noaa-nwm-retro-v2-zarr-pds', @@ -138,24 +138,25 @@ print(group) ``` The type of filesystem (e.g. S3, https, etc..) is inferred from the scheme of the url (e.g. s3 for "**s3**://noaa-nwm-retro-v2-zarr-pds"). -In case a specific filesystem is needed, one can explicitly create it. For example to create an S3 filesystem: +In case a specific filesystem is needed, one can explicitly create it. For example to create an S3 filesystem +(note that the filesystem must be created with `asynchronous=True`): ```python exec="true" session="storage" source="above" result="ansi" # Note: requires s3fs to be installed import fsspec -fs = fsspec.filesystem( - 's3', anon=True, asynchronous=True, - client_kwargs={'endpoint_url': "https://noaa-nwm-retro-v2-zarr-pds.s3.amazonaws.com"} -) -store = zarr.storage.FsspecStore(fs) +fs = fsspec.filesystem('s3', anon=True, asynchronous=True) +store = zarr.storage.FsspecStore(fs, path='noaa-nwm-retro-v2-zarr-pds', read_only=True) print(store) ``` +When using an S3-compatible service other than AWS, pass the service endpoint to the +filesystem via `client_kwargs={'endpoint_url': 'https://...'}`. + ### Memory Store -The [`zarr.storage.MemoryStore`][] is an in-memory store that allows for serialization of -Zarr data (metadata and chunks) to a dictionary: +The [`zarr.storage.MemoryStore`][] stores Zarr data (metadata and chunks) in an +in-memory dictionary: ```python exec="true" session="storage" source="above" result="ansi" data = {} @@ -199,3 +200,5 @@ print(group.info) Zarr-Python [`zarr.abc.store.Store`][] API is meant to be extended. The Store Abstract Base Class includes all of the methods needed to be a fully operational store in Zarr Python. Zarr also provides a test harness for custom stores: [`zarr.testing.store.StoreTests`][]. +See the [Custom stores](extending.md#custom-stores) section of the extending guide for +more on implementing your own store. diff --git a/docs/user-guide/v3_migration.md b/docs/user-guide/v3_migration.md index 1680547d93..f768874667 100644 --- a/docs/user-guide/v3_migration.md +++ b/docs/user-guide/v3_migration.md @@ -16,6 +16,12 @@ migrate your code from version 2 to version 3. If we have missed anything, pleas open a [GitHub issue](https://github.com/zarr-developers/zarr-python/issues/new) so we can improve this guide. +!!! tip + This page is about migrating your *code* from the Zarr-Python 2 API to the + Zarr-Python 3 API. If you want to migrate the *metadata* of stored data from + Zarr format 2 to Zarr format 3, see the `zarr migrate` command described in + the [command-line interface documentation](cli.md). + ## Compatibility target The goals described above necessitated some breaking changes to the API (hence the @@ -56,14 +62,14 @@ the following actions in order: * `zarr.codecs` has changed, see "Codecs" section below for more information * `zarr.context` has gone, with no replacement * `zarr.core` remains but should be considered private API - * `zarr.hierarchy` has gone, with no replacement (use `zarr.Group` inplace of `zarr.hierarchy.Group`) + * `zarr.hierarchy` has gone, with no replacement (use `zarr.Group` in place of `zarr.hierarchy.Group`) * `zarr.indexing` has gone, with no replacement * `zarr.meta` has gone, with no replacement * `zarr.meta_v1` has gone, with no replacement * `zarr.sync` has gone, with no replacement * `zarr.types` has gone, with no replacement * `zarr.util` has gone, with no replacement - * `zarr.n5` has gone, see below for an alternative N5 options + * `zarr.n5` has gone, see below for an alternative N5 option 3. Test that your package works with version 3. 4. Update the pin to include `zarr>=3,<4`. @@ -71,8 +77,9 @@ the following actions in order: ## Zarr-Python 2 support window Zarr-Python 2.x is still available, though we recommend migrating to Zarr-Python 3 for -its performance improvements and new features. Security and bug fixes will be made to -the 2.x series for at least six months following the first Zarr-Python 3 release. +its performance improvements and new features. Security and bug fixes were made to +the 2.x series for six months following the first Zarr-Python 3 release (January 2025); +the 2.x series is no longer actively maintained. If you need to use the latest Zarr-Python 2 release, you can install it with: ```console @@ -151,11 +158,9 @@ The following stores have been renamed or changed: | `DirectoryStore` | [`zarr.storage.LocalStore`][] | | `FSStore` | [`zarr.storage.FsspecStore`][] | | `TempStore` | Use [`tempfile.TemporaryDirectory`][] with [`LocalStore`][zarr.storage.LocalStore] | -| `zarr. - A number of deprecated stores were also removed. -See issue #1274 for more details on the removal of these stores. +See [issue #1274](https://github.com/zarr-developers/zarr-python/issues/1274) for more details on the removal of these stores. - `N5Store` - see https://github.com/zarr-developers/n5py for an alternative interface to N5 formatted data. @@ -169,7 +174,7 @@ See issue #1274 for more details on the removal of these stores. The latter five stores in this list do not have an equivalent in Zarr-Python 3. If you are interested in developing a custom store that targets these backends, see -[developing custom stores](storage.md/#developing-custom-stores) or open an +[developing custom stores](storage.md#developing-custom-stores) or open an [issue](https://github.com/zarr-developers/zarr-python/issues) to discuss your use case. ### Codecs @@ -199,23 +204,21 @@ When installing using `pip`: (e.g. [`zarr.create`][], [`zarr.open`][], [`zarr.group`][], [`zarr.array`][]) has been removed. Use `zarr_format` instead. -## 🚧 Work in Progress 🚧 +## Unimplemented Zarr-Python 2 features -Zarr-Python 3 is still under active development, and is not yet fully complete. -The following list summarizes areas of the codebase that we expect to build out -after the 3.0.0 release. If features listed below are important to your use case +A few features of Zarr-Python 2 remain unimplemented in Zarr-Python 3. +If any of the features listed below are important to your use case of Zarr-Python, please open (or comment on) a [GitHub issue](https://github.com/zarr-developers/zarr-python/issues/new). -The following functions / methods have not been ported to Zarr-Python 3 yet: +The following functions / methods have not been ported to Zarr-Python 3: - `zarr.copy` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407)) - `zarr.copy_all` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407)) - `zarr.copy_store` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407)) -- `zarr.Group.move` ([issue #2108](https://github.com/zarr-developers/zarr-python/issues/2108)) The following features (corresponding to function arguments to functions in - `zarr`) have not been ported to Zarr-Python 3 yet. Using these features + `zarr`) have not been ported to Zarr-Python 3. Using these features will raise a warning or a `NotImplementedError`: - `cache_attrs` @@ -224,10 +227,9 @@ The following features (corresponding to function arguments to functions in - `meta_array` - `object_codec` ([issue #2617](https://github.com/zarr-developers/zarr-python/issues/2617)) - `synchronizer` ([issue #1596](https://github.com/zarr-developers/zarr-python/issues/1596)) -- `dimension_separator` The following features that were supported by Zarr-Python 2 have not been ported - to Zarr-Python 3 yet: + to Zarr-Python 3: - Object dtypes ([issue #2616](https://github.com/zarr-developers/zarr-python/issues/2616)) - Ragged arrays ([issue #2618](https://github.com/zarr-developers/zarr-python/issues/2618)) diff --git a/examples/custom_dtype/README.md b/examples/custom_dtype/README.md index c0722d0661..d51c2b514a 100644 --- a/examples/custom_dtype/README.md +++ b/examples/custom_dtype/README.md @@ -11,12 +11,17 @@ The example shows how to: ## Running the Example +The script declares its dependencies inline +([PEP 723](https://peps.python.org/pep-0723/)), so the easiest way to run it is +with [uv](https://docs.astral.sh/uv/), which installs them automatically: + ```bash -python examples/custom_dtype/custom_dtype.py +uv run examples/custom_dtype/custom_dtype.py ``` -Or run with uv: +Alternatively, run it with plain Python, in which case you must first install +`zarr`, `ml_dtypes`, and `pytest` yourself: ```bash -uv run examples/custom_dtype/custom_dtype.py +python examples/custom_dtype/custom_dtype.py ``` diff --git a/mkdocs.yml b/mkdocs.yml index e4e757e630..c264934d60 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -17,16 +17,16 @@ nav: - user-guide/arrays.md - user-guide/groups.md - user-guide/attributes.md + - user-guide/data_types.md - user-guide/storage.md - user-guide/config.md - - user-guide/cli.md - - user-guide/v3_migration.md - - user-guide/data_types.md - user-guide/performance.md + - user-guide/cli.md - user-guide/extending.md - user-guide/gpu.md - user-guide/consolidated_metadata.md - user-guide/experimental.md + - user-guide/v3_migration.md - user-guide/glossary.md - Examples: - user-guide/examples/custom_dtype.md From ad99ca8aa8405579cad31c7769fa12e2e9c33e55 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Wed, 8 Jul 2026 15:00:05 +0200 Subject: [PATCH 03/13] docs: add changelog fragment for #4132 Co-Authored-By: Claude Fable 5 --- changes/4132.doc.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changes/4132.doc.md diff --git a/changes/4132.doc.md b/changes/4132.doc.md new file mode 100644 index 0000000000..3325c82f43 --- /dev/null +++ b/changes/4132.doc.md @@ -0,0 +1,6 @@ +Fixed many documentation errors found in a full review of the user guide, including +prose contradicted by rendered example output on the performance page, invisible +code blocks, an incorrect S3 example, stale "not yet implemented" claims in the +v3 migration guide, and undocumented optional dependency groups. Also improved +navigation order, cross-linking between pages, and coverage of group member +enumeration, bulk attribute updates, and the `use_consolidated` keyword. From f561efa03118b4570143cadc02b477b024faf8ae Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Wed, 8 Jul 2026 22:15:27 +0200 Subject: [PATCH 04/13] docs: standardize on American spelling (behaviour -> behavior) Co-Authored-By: Claude Fable 5 --- docs/contributing.md | 4 ++-- docs/user-guide/cli.md | 2 +- docs/user-guide/consolidated_metadata.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index 11d5cc0a5c..beb99089e0 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -18,7 +18,7 @@ g = zarr.group() # etc. ``` -2. An explanation of why the current behaviour is wrong/not desired, and what you expect instead. +2. An explanation of why the current behavior is wrong/not desired, and what you expect instead. 3. Information about the version of Zarr, along with versions of dependencies and the Python interpreter, and installation information. The version of Zarr can be obtained from the `zarr.__version__` attribute. Please also state how Zarr was installed, e.g., "installed via pip into a virtual environment", or "installed using conda". Information about other packages installed can be obtained by executing `pip freeze` (if using pip to install packages) or `conda env export` (if using conda to install packages) from the operating system command prompt. The version of the Python interpreter can be obtained by running a Python interactive session, e.g.: @@ -380,7 +380,7 @@ Releases are classified by the library changes contained in that release. This c Minor releases are safe for most users and downstream projects to adopt. -* **patch** releases (for example, `3.1.0` -> `3.1.1`) are for changes that contain no breaking or behaviour changes for downstream projects or users. Examples of changes suitable for a patch release are bugfixes and documentation improvements. +* **patch** releases (for example, `3.1.0` -> `3.1.1`) are for changes that contain no breaking or behavior changes for downstream projects or users. Examples of changes suitable for a patch release are bugfixes and documentation improvements. Users should always feel safe upgrading to the latest patch release. diff --git a/docs/user-guide/cli.md b/docs/user-guide/cli.md index 2d83ccbccd..77f50f5eaf 100644 --- a/docs/user-guide/cli.md +++ b/docs/user-guide/cli.md @@ -96,7 +96,7 @@ zarr remove-metadata v3 path/to/input.zarr By default, this will only allow removal of metadata if a valid alternative exists. For example, you can't remove v2 metadata unless v3 metadata exists at that location. -To override this behaviour use `--force`: +To override this behavior use `--force`: ```bash zarr remove-metadata v3 path/to/input.zarr --force diff --git a/docs/user-guide/consolidated_metadata.md b/docs/user-guide/consolidated_metadata.md index a887b2e313..7030ed6cbc 100644 --- a/docs/user-guide/consolidated_metadata.md +++ b/docs/user-guide/consolidated_metadata.md @@ -85,13 +85,13 @@ print(output.getvalue()) The keys in the consolidated metadata are sorted prior to writing. Keys are sorted in ascending order by path depth, where a path is defined as a sequence of strings joined by `"/"`. For keys with the same path length, lexicographic - order is used to break the tie. This behaviour ensures deterministic metadata + order is used to break the tie. This behavior ensures deterministic metadata output for a given group. ### Controlling the use of consolidated metadata By default, [`zarr.open_group`][] uses consolidated metadata if it is present, and -falls back to reading metadata from the store otherwise. This behaviour can be +falls back to reading metadata from the store otherwise. This behavior can be controlled with the `use_consolidated` keyword. Pass `use_consolidated=False` to ignore consolidated metadata and always read the metadata of child nodes directly from the store: From 3d7be982f92d964c4977630649e2ebe63ad540d8 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 09:57:01 +0200 Subject: [PATCH 05/13] docs: render test="true" and exec="false" fences as code blocks Markdown Exec's superfences fence only claims exec="true" blocks. Fences carrying the repo's other validation markers (test="true", exec="false") failed superfences validation entirely and their contents spilled into the page as raw markdown -- most visibly the custom dtype example, where the included script's PEP 723 header rendered as a series of headings. The GPU page, the quick-start S3 example, and the exec="false" opt-out blocks were equally affected. Add an MkDocs hook that registers a second python fence, tried when Markdown Exec's declines, which strips the validation attributes and delegates to the standard superfences highlighter. Co-Authored-By: Claude Fable 5 --- docs/contributing.md | 5 +++ mkdocs.yml | 3 ++ mkdocs_hooks.py | 82 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 mkdocs_hooks.py diff --git a/docs/contributing.md b/docs/contributing.md index beb99089e0..eaab26fbc7 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -290,6 +290,11 @@ that fits the block). `test="true"`, or `exec="false"` with a reason — so a block can never silently skip validation. A bare ` ```python ` fence, or a typo like `exec="on"`, fails that test. +Markdown Exec only renders `exec="true"` fences; the `mkdocs_hooks.py` hook at the +repository root makes `test="true"` and `exec="false"` fences render as ordinary +highlighted code blocks. Without it, these fences would fail superfences parsing and +their contents would spill into the page as raw markdown. + ##### Marker-bound blocks (GPU, S3) A `test="true"` block that needs special infrastructure declares a pytest marker with diff --git a/mkdocs.yml b/mkdocs.yml index c264934d60..a01667fc00 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -72,6 +72,9 @@ nav: - api/zarr/testing/utils.md - release-notes.md - contributing.md +hooks: + - mkdocs_hooks.py + watch: - src/zarr - docs diff --git a/mkdocs_hooks.py b/mkdocs_hooks.py new file mode 100644 index 0000000000..88368926b9 --- /dev/null +++ b/mkdocs_hooks.py @@ -0,0 +1,82 @@ +"""MkDocs hook that renders validation-marked code fences as ordinary code blocks. + +The docs validation convention (see ``tests/test_docs.py`` and the contributing +guide) requires every python fence to carry ``exec="true"``, ``test="true"``, or +``exec="false" reason="..."``. Markdown Exec's superfences fence only claims +``exec="true"`` blocks; without this hook the remaining marked fences fail +superfences validation and their contents spill into the page as raw markdown +(e.g. the PEP 723 header of the custom dtype example rendered as headings). + +This hook registers a second ``python`` fence, tried when Markdown Exec's +declines, that strips the validation attributes and delegates to the standard +superfences highlighter so the block renders exactly like a plain code fence. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from markdown import Markdown + from mkdocs.config.defaults import MkDocsConfig + +# Mirrors markdown_exec's _to_bool: everything but these means "true". +_FALSY = {"", "no", "off", "false", "0"} + + +def _validator( + language: str, + inputs: dict[str, str], + options: dict[str, Any], + attrs: dict[str, Any], + md: Markdown, +) -> bool: + """Claim fences marked test="true" or exec="false"; leave the rest alone.""" + if "exec" not in inputs and "test" not in inputs: + # Plain fence: let the default superfences pathway highlight it. + return False + if str(inputs.get("exec", "false")).lower() not in _FALSY: + # Executable fence: Markdown Exec's own custom fence handles it. + return False + # Consume the validation attributes so they don't leak into the output. + inputs.clear() + return True + + +def _formatter( + source: str, + language: str, + css_class: str, + options: dict[str, Any], + md: Markdown, + classes: list[str] | None = None, + id_value: str = "", + attrs: dict[str, Any] | None = None, + **kwargs: Any, +) -> str: + """Render with the same highlighter superfences uses for plain fences.""" + fenced = md.preprocessors["fenced_code_block"] + fenced.get_hl_settings() + return fenced.highlight( + src=source, + language=language, + options={}, + md=md, + classes=classes, + id_value=id_value, + attrs=attrs or {}, + ) + + +def on_config(config: MkDocsConfig) -> MkDocsConfig: + superfences = config.setdefault("mdx_configs", {}).setdefault("pymdownx.superfences", {}) + custom_fences = superfences.setdefault("custom_fences", []) + custom_fences.append( + { + "name": "python", + "class": "python", + "validator": _validator, + "format": _formatter, + } + ) + return config From 2d1152b9119fc7bbfc84a66fdd2b32665c9bc97c Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 10:18:58 +0200 Subject: [PATCH 06/13] docs: convert rectilinear chunks notebook to a markdown example page The notebook rendered oddly via mkdocs-jupyter: the PEP 723 dependency header appeared as the first code cell, a bare ConfigSet repr leaked into the output, and the page styling did not match the rest of the site. Since the example cannot execute at build time anyway (it requires an xarray fork with rectilinear chunk grid support plus remote data), convert it to a markdown page in the same style as the custom dtype example, with the captured outputs shown as static blocks and an admonition explaining the requirements. The page URL is unchanged. With no notebooks left in the docs, also drop the mkdocs-jupyter plugin and dependency. Co-Authored-By: Claude Fable 5 --- .../examples/rectilinear_chunks.ipynb | 420 -------------- .../user-guide/examples/rectilinear_chunks.md | 173 ++++++ docs/user-guide/index.md | 2 +- mkdocs.yml | 7 +- pyproject.toml | 1 - uv.lock | 536 ------------------ 6 files changed, 175 insertions(+), 964 deletions(-) delete mode 100644 docs/user-guide/examples/rectilinear_chunks.ipynb create mode 100644 docs/user-guide/examples/rectilinear_chunks.md diff --git a/docs/user-guide/examples/rectilinear_chunks.ipynb b/docs/user-guide/examples/rectilinear_chunks.ipynb deleted file mode 100644 index 37d40a3b7c..0000000000 --- a/docs/user-guide/examples/rectilinear_chunks.ipynb +++ /dev/null @@ -1,420 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "da9139cc", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:20.792275Z", - "iopub.status.busy": "2026-03-30T13:18:20.792050Z", - "iopub.status.idle": "2026-03-30T13:18:20.801655Z", - "shell.execute_reply": "2026-03-30T13:18:20.797952Z", - "shell.execute_reply.started": "2026-03-30T13:18:20.792253Z" - } - }, - "outputs": [], - "source": [ - "# /// script\n", - "# requires-python = \">=3.12\"\n", - "# dependencies = [\n", - "# \"dask\",\n", - "# \"healpix-geo\",\n", - "# \"matplotlib\",\n", - "# \"numpy\",\n", - "# \"obstore\",\n", - "# \"xarray\",\n", - "# \"zarr\",\n", - "# ]\n", - "#\n", - "# [tool.uv.sources]\n", - "# zarr = { git = \"https://github.com/zarr-developers/zarr-python\", branch = \"main\" }\n", - "# xarray = { git = \"https://github.com/maxrjones/xarray\", branch = \"poc/unified-zarr-chunk-grid\" }\n", - "# ///" - ] - }, - { - "cell_type": "markdown", - "id": "71gnhfq4pfe", - "metadata": {}, - "source": [ - "# Rectilinear Chunk Grids\n", - "\n", - "This notebook demonstrates the unified chunk grid implementation from [#3802](https://github.com/zarr-developers/zarr-python/pull/3802), which adds support for rectilinear (variable) chunk grids.\n", - "\n", - "Note that it requires installing from a fork of Xarray; this will ideally be incorporated in the codebase and included in a future Xarray release.\n", - "\n", - "Rectilinear grids allow different chunk sizes along each dimension, which is useful for data that doesn't partition evenly. For example, sparse HEALPix cells grouped by parent tile, boundary-padded HPC arrays, or ingesting existing variable-chunked datasets via VirtualiZarr." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "9e9nyjdx06f", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:20.802629Z", - "iopub.status.busy": "2026-03-30T13:18:20.802471Z", - "iopub.status.idle": "2026-03-30T13:18:21.183147Z", - "shell.execute_reply": "2026-03-30T13:18:21.182751Z", - "shell.execute_reply.started": "2026-03-30T13:18:20.802615Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import tempfile\n", - "from pathlib import Path\n", - "import json\n", - "\n", - "import numpy as np\n", - "import xarray as xr\n", - "from healpix_geo import nested\n", - "from obstore.store import HTTPStore\n", - "\n", - "import zarr\n", - "from zarr.storage import ObjectStore\n", - "\n", - "zarr.config.set({'async.concurrency': 128}) # Increase concurrency for better performance with obstore\n", - "zarr.config.set({\"array.rectilinear_chunks\": True}) # Opt-in to rectilinear chunks\n" - ] - }, - { - "cell_type": "markdown", - "id": "kj1o9xik9l", - "metadata": {}, - "source": [ - "## 1. Inspect HEALPix dataset\n", - "\n", - "Load the remote Zarr store to understand the data structure before chunking it." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "v6cot74r1gq", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:21.183653Z", - "iopub.status.busy": "2026-03-30T13:18:21.183505Z", - "iopub.status.idle": "2026-03-30T13:18:22.028419Z", - "shell.execute_reply": "2026-03-30T13:18:22.027356Z", - "shell.execute_reply.started": "2026-03-30T13:18:21.183644Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Members: [('cell_ids', ), ('da', )]\n", - "Attrs: {}\n", - "Write chunk sizes: ((55611, 55611, 55611, 55609),)\n" - ] - } - ], - "source": [ - "ob_store = HTTPStore.from_url(\"https://data-taos.ifremer.fr/GRID4EARTH/no_chunk_healpix.zarr\")\n", - "store = ObjectStore(ob_store)\n", - "g = zarr.open_group(store, mode=\"r\", zarr_format=2, use_consolidated=True)\n", - "arr = g['da']\n", - "\n", - "print(\"Members:\", list(g.members()))\n", - "print(\"Attrs:\", dict(g.attrs))\n", - "print(\"Write chunk sizes:\", arr.write_chunk_sizes)" - ] - }, - { - "cell_type": "markdown", - "id": "wmuqi66d46", - "metadata": {}, - "source": [ - "## 2. HEALPix-style variable chunking\n", - "\n", - "Inspired by [this use case](https://github.com/zarr-developers/zarr-python/pull/3534#issuecomment-3848669859): HEALPix grids where cells are grouped by parent tile at a coarser resolution level, producing variable-sized chunks along the cell dimension when accounting for sparsity." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "90bc91b9", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:22.029842Z", - "iopub.status.busy": "2026-03-30T13:18:22.029258Z", - "iopub.status.idle": "2026-03-30T13:18:23.629597Z", - "shell.execute_reply": "2026-03-30T13:18:23.628896Z", - "shell.execute_reply.started": "2026-03-30T13:18:22.029824Z" - } - }, - "outputs": [], - "source": [ - "da = xr.open_zarr(\n", - " store,\n", - " zarr_format=2,\n", - " consolidated=True,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "0d7785b0-d72f-4ef8-8a57-91d61f07be96", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:23.630244Z", - "iopub.status.busy": "2026-03-30T13:18:23.629978Z", - "iopub.status.idle": "2026-03-30T13:18:23.633850Z", - "shell.execute_reply": "2026-03-30T13:18:23.632930Z", - "shell.execute_reply.started": "2026-03-30T13:18:23.630232Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "10" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "depth = da.cell_ids.attrs['level']\n", - "depth" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "72c80224-dcac-4724-8caf-5717b29a25d5", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:23.634211Z", - "iopub.status.busy": "2026-03-30T13:18:23.634119Z", - "iopub.status.idle": "2026-03-30T13:18:23.642291Z", - "shell.execute_reply": "2026-03-30T13:18:23.641668Z", - "shell.execute_reply.started": "2026-03-30T13:18:23.634203Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603,\n", - " 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879,\n", - " 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096,\n", - " 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096,\n", - " 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714,\n", - " 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438,\n", - " 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23])" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "new_depth = depth-6\n", - "parents = nested.zoom_to(da.cell_ids, depth=depth, new_depth=new_depth)\n", - "_, chunk_sizes =np.unique(parents, return_counts=True)\n", - "chunk_sizes" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "a79a281b-ca74-49c3-a467-60490a4ad63e", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:23.642721Z", - "iopub.status.busy": "2026-03-30T13:18:23.642622Z", - "iopub.status.idle": "2026-03-30T13:18:23.649165Z", - "shell.execute_reply": "2026-03-30T13:18:23.648723Z", - "shell.execute_reply.started": "2026-03-30T13:18:23.642712Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)})" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "da = da.chunk({\"cell_ids\": tuple(chunk_sizes.tolist())})\n", - "da.chunks" - ] - }, - { - "cell_type": "markdown", - "id": "bsp6y7otkzb", - "metadata": {}, - "source": [ - "## 3. Write as rectilinear Zarr V3\n", - "\n", - "Write the variable-chunked dataset to a local Zarr V3 store with rectilinear chunk grids enabled." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "ribguojdr0s", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:23.649823Z", - "iopub.status.busy": "2026-03-30T13:18:23.649737Z", - "iopub.status.idle": "2026-03-30T13:18:24.089390Z", - "shell.execute_reply": "2026-03-30T13:18:24.088640Z", - "shell.execute_reply.started": "2026-03-30T13:18:23.649815Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Written to: /var/folders/70/hc_nynms54d8lp67z4rsfctc0000gp/T/tmp6dibcrho/healpix_rectilinear.zarr\n" - ] - } - ], - "source": [ - "output_path = Path(tempfile.mkdtemp()) / \"healpix_rectilinear.zarr\"\n", - "\n", - "encoding = {\n", - " \"da\": {\"chunks\": [chunk_sizes.tolist()]},\n", - " \"cell_ids\": {\"chunks\": [chunk_sizes.tolist()]},\n", - "}\n", - "\n", - "da.to_zarr(output_path, zarr_format=3, mode=\"w\", encoding=encoding, consolidated=False)\n", - "\n", - "print(f\"Written to: {output_path}\")" - ] - }, - { - "cell_type": "markdown", - "id": "rbfm1hn63g9", - "metadata": {}, - "source": [ - "## 4. Verify rectilinear metadata\n", - "\n", - "Inspect the output store to confirm the chunk grid is serialized as `\"rectilinear\"` in `zarr.json`,\n", - "following the [rectilinear chunk grid extension spec](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear).\n", - "\n", - "Key things to look for in `chunk_grid`:\n", - "- **`name`**: `\"rectilinear\"` (the extension identifier)\n", - "- **`configuration.kind`**: `\"inline\"` (edge lengths stored directly in metadata)\n", - "- **`configuration.chunk_shapes`**: one entry per dimension — here a single list for the 1D `cell_ids` axis. Each element is either:\n", - " - a **bare integer** for a unique edge length (e.g., `25`, `645`)\n", - " - a **`[value, count]` array** using [run-length encoding](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear#run-length-encoding) for consecutive repeated sizes (e.g., `[4096, 4]` means four consecutive chunks of size 4096)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "mpdn5hxp7lp", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:24.090312Z", - "iopub.status.busy": "2026-03-30T13:18:24.090192Z", - "iopub.status.idle": "2026-03-30T13:18:24.093595Z", - "shell.execute_reply": "2026-03-30T13:18:24.092908Z", - "shell.execute_reply.started": "2026-03-30T13:18:24.090303Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'name': 'rectilinear', 'configuration': {'kind': 'inline', 'chunk_shapes': [[25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, [4096, 2], 3327, 4047, [4096, 2], 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, [4096, 4], 3515, 1395, 4096, 3622, [4096, 2], 3875, [4096, 5], 2034, 4096, 358, 3991, [4096, 4], 2714, 1210, [4096, 4], 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23]]}}\n" - ] - } - ], - "source": [ - "\n", - "# Read the zarr.json for the 'da' array\n", - "da_meta_path = output_path / \"da\" / \"zarr.json\"\n", - "meta = json.loads(da_meta_path.read_text())\n", - "print(meta['chunk_grid'])" - ] - }, - { - "cell_type": "markdown", - "id": "inz7s8ugu2c", - "metadata": {}, - "source": [ - "## 5. Round-trip verification\n", - "\n", - "Read the rectilinear store back and confirm the chunk sizes are preserved." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "308gxly6r3j", - "metadata": { - "execution": { - "iopub.execute_input": "2026-03-30T13:18:24.094252Z", - "iopub.status.busy": "2026-03-30T13:18:24.094013Z", - "iopub.status.idle": "2026-03-30T13:18:24.117313Z", - "shell.execute_reply": "2026-03-30T13:18:24.116670Z", - "shell.execute_reply.started": "2026-03-30T13:18:24.094242Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Round-trip chunk sizes: Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)})\n" - ] - } - ], - "source": [ - "roundtrip = xr.open_zarr(output_path, zarr_format=3, consolidated=False)\n", - "\n", - "print(\"Round-trip chunk sizes:\", roundtrip.chunks)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/user-guide/examples/rectilinear_chunks.md b/docs/user-guide/examples/rectilinear_chunks.md new file mode 100644 index 0000000000..098cdf1e2f --- /dev/null +++ b/docs/user-guide/examples/rectilinear_chunks.md @@ -0,0 +1,173 @@ +# Rectilinear Chunk Grids + +This example demonstrates rectilinear (variable-sized) chunk grids, introduced in +[#3802](https://github.com/zarr-developers/zarr-python/pull/3802). Rectilinear grids +allow different chunk sizes along each dimension, which is useful for data that +doesn't partition evenly — for example, sparse HEALPix cells grouped by parent tile, +boundary-padded HPC arrays, or ingesting existing variable-chunked datasets via +VirtualiZarr. See [Rectilinear (variable) chunk grids](../arrays.md#rectilinear-variable-chunk-grids) +in the arrays guide for an introduction to the feature. + +The example chunks a HEALPix dataset by parent tile, writes it as a Zarr v3 array +with a rectilinear chunk grid, and verifies the round trip through +[Xarray](https://xarray.dev). + +!!! warning "Experimental" + Rectilinear chunk grids are an experimental feature and may change in future + releases. In addition, this example currently requires + [a fork of Xarray](https://github.com/maxrjones/xarray/tree/poc/unified-zarr-chunk-grid) + with rectilinear chunk grid support (this will ideally be incorporated into a + future Xarray release), as well as the `dask`, `healpix-geo`, and `obstore` + packages, and it reads an example dataset from a remote server. For these + reasons the code on this page is not executed when the documentation is built; + the outputs shown were captured from a live run. + +## Setup + +Rectilinear chunk grids are disabled by default and must be explicitly enabled via +the `array.rectilinear_chunks` configuration option: + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +import json +import tempfile +from pathlib import Path + +import numpy as np +import xarray as xr +from healpix_geo import nested +from obstore.store import HTTPStore + +import zarr +from zarr.storage import ObjectStore + +# Increase concurrency for better performance with obstore +zarr.config.set({'async.concurrency': 128}) +# Opt in to rectilinear chunks +zarr.config.set({'array.rectilinear_chunks': True}) +``` + +## Inspect the HEALPix dataset + +Load the remote Zarr store to understand the data structure before chunking it: + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +ob_store = HTTPStore.from_url("https://data-taos.ifremer.fr/GRID4EARTH/no_chunk_healpix.zarr") +store = ObjectStore(ob_store) +g = zarr.open_group(store, mode="r", zarr_format=2, use_consolidated=True) +arr = g['da'] + +print("Members:", list(g.members())) +print("Attrs:", dict(g.attrs)) +print("Write chunk sizes:", arr.write_chunk_sizes) +``` + +```text +Members: [('cell_ids', ), ('da', )] +Attrs: {} +Write chunk sizes: ((55611, 55611, 55611, 55609),) +``` + +## HEALPix-style variable chunking + +Inspired by [this use case](https://github.com/zarr-developers/zarr-python/pull/3534#issuecomment-3848669859): +HEALPix grids where cells are grouped by parent tile at a coarser resolution level, +producing variable-sized chunks along the cell dimension when accounting for sparsity. + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +da = xr.open_zarr( + store, + zarr_format=2, + consolidated=True, +) + +depth = da.cell_ids.attrs['level'] +new_depth = depth - 6 +parents = nested.zoom_to(da.cell_ids, depth=depth, new_depth=new_depth) +_, chunk_sizes = np.unique(parents, return_counts=True) +print(chunk_sizes) +``` + +```text +[ 25 645 1510 2363 3203 74 769 3963 4096 233 1603 2450 4096 4096 + 3327 4047 4096 4096 1278 2113 4096 3879 4096 3842 2173 983 4046 2187 + 4095 1369 4096 4096 4096 4096 3515 1395 4096 3622 4096 4096 3875 4096 + 4096 4096 4096 4096 2034 4096 358 3991 4096 4096 4096 4096 2714 1210 + 4096 4096 4096 4096 92 3826 4096 2629 4096 1438 4096 353 4078 3410 + 2407 226 132 2738 1223 23] +``` + +Rechunk the dataset with these variable-sized chunks: + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +da = da.chunk({"cell_ids": tuple(chunk_sizes.tolist())}) +print(da.chunks) +``` + +```text +Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)}) +``` + +## Write as rectilinear Zarr v3 + +Write the variable-chunked dataset to a local Zarr v3 store with rectilinear chunk +grids enabled: + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +output_path = Path(tempfile.mkdtemp()) / "healpix_rectilinear.zarr" + +encoding = { + "da": {"chunks": [chunk_sizes.tolist()]}, + "cell_ids": {"chunks": [chunk_sizes.tolist()]}, +} + +da.to_zarr(output_path, zarr_format=3, mode="w", encoding=encoding, consolidated=False) + +print(f"Written to: {output_path}") +``` + +```text +Written to: /var/folders/.../T/tmp6dibcrho/healpix_rectilinear.zarr +``` + +## Verify the rectilinear metadata + +Inspect the output store to confirm the chunk grid is serialized as `"rectilinear"` +in `zarr.json`, following the +[rectilinear chunk grid extension spec](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear). + +Key things to look for in `chunk_grid`: + +- **`name`**: `"rectilinear"` (the extension identifier) +- **`configuration.kind`**: `"inline"` (edge lengths stored directly in metadata) +- **`configuration.chunk_shapes`**: one entry per dimension — here a single list for + the 1D `cell_ids` axis. Each element is either: + - a **bare integer** for a unique edge length (e.g., `25`, `645`) + - a **`[value, count]` array** using + [run-length encoding](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear#run-length-encoding) + for consecutive repeated sizes (e.g., `[4096, 4]` means four consecutive chunks + of size 4096) + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +# Read the zarr.json for the 'da' array +da_meta_path = output_path / "da" / "zarr.json" +meta = json.loads(da_meta_path.read_text()) +print(meta['chunk_grid']) +``` + +```text +{'name': 'rectilinear', 'configuration': {'kind': 'inline', 'chunk_shapes': [[25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, [4096, 2], 3327, 4047, [4096, 2], 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, [4096, 4], 3515, 1395, 4096, 3622, [4096, 2], 3875, [4096, 5], 2034, 4096, 358, 3991, [4096, 4], 2714, 1210, [4096, 4], 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23]]}} +``` + +## Round-trip verification + +Read the rectilinear store back and confirm the chunk sizes are preserved: + +```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data" +roundtrip = xr.open_zarr(output_path, zarr_format=3, consolidated=False) + +print("Round-trip chunk sizes:", roundtrip.chunks) +``` + +```text +Round-trip chunk sizes: Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)}) +``` diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 6b4325c8fd..6b9a547776 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -42,7 +42,7 @@ Take your skills to the next level: Worked, end-to-end examples: - **[Custom Data Type](examples/custom_dtype.md)** - Extend Zarr-Python with a user-defined data type -- **[Rectilinear Chunk Grids](examples/rectilinear_chunks.ipynb)** - Use variable-sized chunks along each dimension +- **[Rectilinear Chunk Grids](examples/rectilinear_chunks.md)** - Use variable-sized chunks along each dimension ## Reference diff --git a/mkdocs.yml b/mkdocs.yml index a01667fc00..a4c37a2c17 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -30,7 +30,7 @@ nav: - user-guide/glossary.md - Examples: - user-guide/examples/custom_dtype.md - - user-guide/examples/rectilinear_chunks.ipynb + - user-guide/examples/rectilinear_chunks.md - API Reference: - api/zarr/index.md - api/zarr/array.md @@ -131,11 +131,6 @@ extra_css: plugins: - autorefs - search - - mkdocs-jupyter: - include: ["docs/user-guide/examples/*.ipynb"] - execute: false - ignore_h1_titles: true - show_input: true - markdown-exec - mkdocstrings: enable_inventory: true diff --git a/pyproject.toml b/pyproject.toml index 6a7238ff8f..1ecfb6a62f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -126,7 +126,6 @@ docs = [ "mkdocstrings==1.0.4", "mkdocstrings-python==2.0.4", "mike==2.2.0", - "mkdocs-jupyter==0.26.3", "mkdocs-redirects==1.2.3", "markdown-exec[ansi]==1.12.1", "griffe-inherited-docstrings==1.1.3", diff --git a/uv.lock b/uv.lock index 9bb186b8f7..57adb18e86 100644 --- a/uv.lock +++ b/uv.lock @@ -191,15 +191,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462, upload-time = "2024-08-03T19:00:11.134Z" }, ] -[[package]] -name = "appnope" -version = "0.1.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, -] - [[package]] name = "ast-serialize" version = "0.3.0" @@ -256,15 +247,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/97/4ee9b0438e85bf0a808a89ef0be357319252ab27e1b313ae0aef7aeaa5a6/astroid-4.1.2-py3-none-any.whl", hash = "sha256:21312e682c0866dc5a309ee57e4b88ea92751b9955a58b1c31371cbbeb088707", size = 279956, upload-time = "2026-03-22T19:16:40.062Z" }, ] -[[package]] -name = "asttokens" -version = "3.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, -] - [[package]] name = "attrs" version = "26.1.0" @@ -324,36 +306,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3e/5c/fb93d3092640a24dfb7bd7727a24016d7c01774ca013e60efd3f683c8002/backrefs-7.0-py314-none-any.whl", hash = "sha256:a6448b28180e3ca01134c9cf09dcebafad8531072e09903c5451748a05f24bc9", size = 412349, upload-time = "2026-04-28T16:28:02.412Z" }, ] -[[package]] -name = "beautifulsoup4" -version = "4.14.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "soupsieve" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, -] - -[[package]] -name = "bleach" -version = "6.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "webencodings" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/48/3c/e12ac860709702bd5ebeb9b56a4fe334f1001246ee1b8f2b7ee28912df7d/bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452", size = 204857, upload-time = "2026-06-05T13:01:13.734Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/58/9d/40b6267367182187139a4000b82a3b287d84d745bccd808e75d916920e9d/bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081", size = 165109, upload-time = "2026-06-05T13:01:12.504Z" }, -] - -[package.optional-dependencies] -css = [ - { name = "tinycss2" }, -] - [[package]] name = "blinker" version = "1.9.0" @@ -664,15 +616,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "comm" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, -] - [[package]] name = "coverage" version = "7.14.1" @@ -853,36 +796,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/80/5e05de89ba61df072aab6f8a6ee3ffeec57db68a0a456825b3b4ce608426/cupy_cuda12x-14.1.1-cp314-cp314t-manylinux2014_x86_64.whl", hash = "sha256:238080487174268d0f09770fe518de7c5b206527bef5c6792aef7ba0626a1c48", size = 132635338, upload-time = "2026-06-01T04:53:35.229Z" }, ] -[[package]] -name = "debugpy" -version = "1.8.20" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686, upload-time = "2026-01-29T23:03:42.023Z" }, - { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588, upload-time = "2026-01-29T23:03:43.314Z" }, - { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372, upload-time = "2026-01-29T23:03:45.526Z" }, - { url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3", size = 5372835, upload-time = "2026-01-29T23:03:47.245Z" }, - { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560, upload-time = "2026-01-29T23:03:48.738Z" }, - { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272, upload-time = "2026-01-29T23:03:50.169Z" }, - { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208, upload-time = "2026-01-29T23:03:51.547Z" }, - { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930, upload-time = "2026-01-29T23:03:53.585Z" }, - { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066, upload-time = "2026-01-29T23:03:54.999Z" }, - { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425, upload-time = "2026-01-29T23:03:56.518Z" }, - { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407, upload-time = "2026-01-29T23:03:58.481Z" }, - { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521, upload-time = "2026-01-29T23:03:59.864Z" }, - { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, -] - -[[package]] -name = "decorator" -version = "5.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, -] - [[package]] name = "defusedxml" version = "0.7.1" @@ -936,24 +849,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, ] -[[package]] -name = "executing" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, -] - -[[package]] -name = "fastjsonschema" -version = "2.21.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, -] - [[package]] name = "flask" version = "3.1.3" @@ -1186,64 +1081,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] -[[package]] -name = "ipykernel" -version = "7.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "appnope", marker = "sys_platform == 'darwin'" }, - { name = "comm" }, - { name = "debugpy" }, - { name = "ipython" }, - { name = "jupyter-client" }, - { name = "jupyter-core" }, - { name = "matplotlib-inline" }, - { name = "nest-asyncio" }, - { name = "packaging" }, - { name = "psutil" }, - { name = "pyzmq" }, - { name = "tornado" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, -] - -[[package]] -name = "ipython" -version = "9.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "decorator" }, - { name = "ipython-pygments-lexers" }, - { name = "jedi" }, - { name = "matplotlib-inline" }, - { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit" }, - { name = "psutil" }, - { name = "pygments" }, - { name = "stack-data" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/87cda5842cf5c31837c06ddb588e11c3c35d8ece89b7a0108c06b8c9b00a/ipython-9.13.0.tar.gz", hash = "sha256:7e834b6afc99f020e3f05966ced34792f40267d64cb1ea9043886dab0dde5967", size = 4430549, upload-time = "2026-04-24T12:24:55.221Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/86/3060e8029b7cc505cce9a0137431dda81d0a3fde93a8f0f50ee0bf37a795/ipython-9.13.0-py3-none-any.whl", hash = "sha256:57f9d4639e20818d328d287c7b549af3d05f12486ea8f2e7f73e52a36ec4d201", size = 627274, upload-time = "2026-04-24T12:24:53.038Z" }, -] - -[[package]] -name = "ipython-pygments-lexers" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, -] - [[package]] name = "itsdangerous" version = "2.2.0" @@ -1253,18 +1090,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, ] -[[package]] -name = "jedi" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "parso" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/46/b7/a3635f6a2d7cf5b5dd98064fc1d5fbbafcb25477bcea204a3a92145d158b/jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011", size = 3119416, upload-time = "2026-05-01T23:38:47.814Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/93/242e2eab5fe682ffcb8b0084bde703a41d51e17ee0f3a31ff0d9d813620a/jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67", size = 4884812, upload-time = "2026-05-01T23:38:43.919Z" }, -] - [[package]] name = "jinja2" version = "3.1.6" @@ -1369,60 +1194,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] -[[package]] -name = "jupyter-client" -version = "8.8.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jupyter-core" }, - { name = "python-dateutil" }, - { name = "pyzmq" }, - { name = "tornado" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020, upload-time = "2026-01-08T13:55:47.938Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" }, -] - -[[package]] -name = "jupyter-core" -version = "5.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "platformdirs" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, -] - -[[package]] -name = "jupyterlab-pygments" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, -] - -[[package]] -name = "jupytext" -version = "1.19.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "mdit-py-plugins" }, - { name = "nbformat" }, - { name = "packaging" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/4f13fcba0ed05965a48fca197d89fb8c78c4b61051dc0c9ee9ed92e77a8d/jupytext-1.19.2.tar.gz", hash = "sha256:da6198a42406a09142b6b26ebc46a3ec7077f525222a8f12b1811a0e289a2216", size = 4309931, upload-time = "2026-05-10T17:10:40.345Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/65/b4b86e5fa07543bfbbcdc6c9f7f9f561e66a5f3539992e3009973f2b1314/jupytext-1.19.2-py3-none-any.whl", hash = "sha256:8a31e896c7e9215841783aade24336e945543057e1c2d7f00b22f9e870348688", size = 170653, upload-time = "2026-05-10T17:10:38.418Z" }, -] - [[package]] name = "lazy-object-proxy" version = "1.12.0" @@ -1616,30 +1387,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] -[[package]] -name = "matplotlib-inline" -version = "0.2.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bd/c0/9f7c9a46090390368a4d7bcb76bb87a4a36c421e4c0792cdb53486ffac7a/matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79", size = 8150, upload-time = "2026-05-08T17:33:33.49Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/09/5b161152e2d90f7b87f781c2e1267494aef9c32498df793f73ad0a0a494a/matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6", size = 9534, upload-time = "2026-05-08T17:33:32.055Z" }, -] - -[[package]] -name = "mdit-py-plugins" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/59/fc/f8d0863f8862f25602c0404d75568e89fb6b4109804645e5cdfb1be5cf56/mdit_py_plugins-0.6.1.tar.gz", hash = "sha256:a2bca0f039f39dbd35fb74ae1b5f998608c437463371f0ff7f49a19a17a114d0", size = 56114, upload-time = "2026-05-13T09:03:38.91Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl", hash = "sha256:214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d", size = 66663, upload-time = "2026-05-13T09:03:37.76Z" }, -] - [[package]] name = "mdurl" version = "0.1.2" @@ -1675,15 +1422,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl", hash = "sha256:e1f4981c1152eec7c2490a3401142292cc47d686194188416db2648fdfe1d040", size = 34026, upload-time = "2026-04-14T04:59:02.602Z" }, ] -[[package]] -name = "mistune" -version = "3.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/84/620cc3f7e3adf6f5067e10f4dbae71295d8f9e16d5d3f9ef97c40f2f592c/mistune-3.2.1.tar.gz", hash = "sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28", size = 98003, upload-time = "2026-05-03T14:33:22.312Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/7f/a946aa4f8752b37102b41e64dca18a1976ac705c3a0d1dfe74d820a02552/mistune-3.2.1-py3-none-any.whl", hash = "sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048", size = 53749, upload-time = "2026-05-03T14:33:20.551Z" }, -] - [[package]] name = "mkdocs" version = "1.6.1" @@ -1736,23 +1474,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" }, ] -[[package]] -name = "mkdocs-jupyter" -version = "0.26.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ipykernel" }, - { name = "jupytext" }, - { name = "mkdocs" }, - { name = "mkdocs-material" }, - { name = "nbconvert" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/00/aa/f8d15409a9a3112486994a80d5a975694c7d145c4f8b5b484aeb383420ef/mkdocs_jupyter-0.26.3.tar.gz", hash = "sha256:e1e8bd48a1b96542e84e3028e3066112bac7b94d95ab69f8b91305c84003ca26", size = 1628353, upload-time = "2026-04-17T18:56:31.517Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl", hash = "sha256:cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82", size = 1459740, upload-time = "2026-04-17T18:56:30.031Z" }, -] - [[package]] name = "mkdocs-material" version = "9.7.6" @@ -2087,70 +1808,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] -[[package]] -name = "nbclient" -version = "0.10.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jupyter-client" }, - { name = "jupyter-core" }, - { name = "nbformat" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9", size = 62554, upload-time = "2025-12-23T07:45:46.369Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440", size = 25465, upload-time = "2025-12-23T07:45:44.51Z" }, -] - -[[package]] -name = "nbconvert" -version = "7.17.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "bleach", extra = ["css"] }, - { name = "defusedxml" }, - { name = "jinja2" }, - { name = "jupyter-core" }, - { name = "jupyterlab-pygments" }, - { name = "markupsafe" }, - { name = "mistune" }, - { name = "nbclient" }, - { name = "nbformat" }, - { name = "packaging" }, - { name = "pandocfilters" }, - { name = "pygments" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" }, -] - -[[package]] -name = "nbformat" -version = "5.10.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fastjsonschema" }, - { name = "jsonschema" }, - { name = "jupyter-core" }, - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, -] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, -] - [[package]] name = "networkx" version = "3.6.1" @@ -2367,24 +2024,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, ] -[[package]] -name = "pandocfilters" -version = "1.5.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, -] - -[[package]] -name = "parso" -version = "0.8.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/4b/90c937815137d43ce71ba043cd3566221e9df6b9c805f24b5d138c9d40a7/parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1", size = 401824, upload-time = "2026-05-01T23:13:02.138Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/99/5d/8268b644392ee874ee82a635cd0df1773de230bde356c38de28e298392cc/parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c", size = 107025, upload-time = "2026-05-01T23:12:58.867Z" }, -] - [[package]] name = "pathable" version = "0.5.0" @@ -2412,18 +2051,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, ] -[[package]] -name = "pexpect" -version = "4.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ptyprocess" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, -] - [[package]] name = "pillow" version = "12.2.0" @@ -2511,18 +2138,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] -[[package]] -name = "prompt-toolkit" -version = "3.0.52" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wcwidth" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, -] - [[package]] name = "propcache" version = "0.5.2" @@ -2640,52 +2255,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/4d/fc923f5c85318ee8cc903566dc4e0ebe41b2dfc1d2ecf5546db232397ed6/properdocs-1.6.7-py3-none-any.whl", hash = "sha256:6fa0cfa2e01bf338f684892c8a506cf70ea88ae7f3479c933b6fa20168101cbd", size = 225406, upload-time = "2026-03-20T20:07:46.875Z" }, ] -[[package]] -name = "psutil" -version = "7.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, - { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, - { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, - { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, - { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, - { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, - { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, - { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, - { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, - { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, - { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, - { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, - { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, - { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, - { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, - { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, - { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, - { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, - { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, -] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, -] - -[[package]] -name = "pure-eval" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, -] - [[package]] name = "py-cpuinfo" version = "9.0.0" @@ -3064,49 +2633,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, ] -[[package]] -name = "pyzmq" -version = "27.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi", marker = "implementation_name == 'pypy'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, - { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, - { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, - { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, - { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, - { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, - { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, - { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, - { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, - { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" }, - { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" }, - { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, - { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, - { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, - { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, - { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, - { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, - { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, - { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, - { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, - { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, - { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" }, - { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, - { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, - { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, - { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, - { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, - { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, - { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, - { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, -] - [[package]] name = "referencing" version = "0.37.0" @@ -3449,15 +2975,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] -[[package]] -name = "soupsieve" -version = "2.8.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, -] - [[package]] name = "sphinx" version = "9.1.0" @@ -3540,20 +3057,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, ] -[[package]] -name = "stack-data" -version = "0.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "asttokens" }, - { name = "executing" }, - { name = "pure-eval" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, -] - [[package]] name = "sympy" version = "1.14.0" @@ -3587,23 +3090,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl", hash = "sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738", size = 41328, upload-time = "2026-05-10T07:38:23.517Z" }, ] -[[package]] -name = "tornado" -version = "6.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/64/24/95ec527ad67b76d59299e5465b3935d05e4294b7e0290a3924b7487df30b/tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2", size = 519252, upload-time = "2026-06-08T17:34:51.232Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/02/dc/c7043cab6fed8ae159fc1923ce829ada35c4dbd797d408a43858ffaf9639/tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163", size = 448543, upload-time = "2026-06-08T17:34:38.052Z" }, - { url = "https://files.pythonhosted.org/packages/92/4f/090b1431e5a43df696feceffc268c5383cc079ecb5f08ce58f917109aafe/tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100", size = 446707, upload-time = "2026-06-08T17:34:39.594Z" }, - { url = "https://files.pythonhosted.org/packages/37/d8/ef374952fd5da67d4463122c2b8e5a96536ec10b4b339254c6dcde81d01c/tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972", size = 449774, upload-time = "2026-06-08T17:34:41.204Z" }, - { url = "https://files.pythonhosted.org/packages/35/37/d434c73f4c6e014b745b9b37085f34f40c022f007efff3d7fe65991899f3/tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b", size = 450745, upload-time = "2026-06-08T17:34:42.531Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/56b9aff361d7f1ab728a805ec7d7ea835f8807afa9f5cc690ea0e630efb9/tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92", size = 450578, upload-time = "2026-06-08T17:34:43.787Z" }, - { url = "https://files.pythonhosted.org/packages/02/30/a7444fb23aa76860a14198fab96ac79f1866b0a6e19e26c4381b0938e50f/tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5", size = 449985, upload-time = "2026-06-08T17:34:45.326Z" }, - { url = "https://files.pythonhosted.org/packages/5c/42/5f0e56c01e8d9d36f4e23f367b85ae6cae0c1ecddd5e6977d8388ad27488/tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4", size = 451047, upload-time = "2026-06-08T17:34:46.784Z" }, - { url = "https://files.pythonhosted.org/packages/c9/a4/b393076ffb21b469eec5b328a0534cf03a3b90bfc6b1f09507cdd075d938/tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4", size = 451485, upload-time = "2026-06-08T17:34:48.248Z" }, - { url = "https://files.pythonhosted.org/packages/71/2e/7b1c769803121b809112cf9a00681c472eae1d80e32d7ec0e0bd61d0d0e1/tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796", size = 450506, upload-time = "2026-06-08T17:34:49.702Z" }, -] - [[package]] name = "towncrier" version = "25.8.0" @@ -3617,15 +3103,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/06/8ba22ec32c74ac1be3baa26116e3c28bc0e76a5387476921d20b6fdade11/towncrier-25.8.0-py3-none-any.whl", hash = "sha256:b953d133d98f9aeae9084b56a3563fd2519dfc6ec33f61c9cd2c61ff243fb513", size = 65101, upload-time = "2025-08-30T11:41:53.644Z" }, ] -[[package]] -name = "traitlets" -version = "5.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/22/40f55b26baeab80c2d7b3f1db0682f8954e4617fee7d90ce634022ef05c6/traitlets-5.15.0.tar.gz", hash = "sha256:4fead733f81cf1c4c938e06f8ca4633896833c9d89eff878159457f4d4392971", size = 163197, upload-time = "2026-05-06T08:05:58.016Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/98/a9937a969d018a23badfea0b381f66783649d48e0ea6c41923265c3cbeb3/traitlets-5.15.0-py3-none-any.whl", hash = "sha256:fb36a18867a6803deab09f3c5e0fa81bb7b26a5c9e82501c9933f759166eff40", size = 85877, upload-time = "2026-05-06T08:05:55.853Z" }, -] - [[package]] name = "typer" version = "0.26.7" @@ -3743,15 +3220,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] -[[package]] -name = "wcwidth" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/afaf0f85a9a18fe47a67f1e4422ed6cf1fe642f0ae0a2f81166231303c52/wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0", size = 182132, upload-time = "2026-05-02T16:04:12.653Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/52/e465037f5375f43533d1a80b6923955201596a99142ed524d77b571a1418/wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2", size = 110825, upload-time = "2026-05-02T16:04:11.033Z" }, -] - [[package]] name = "webencodings" version = "0.5.1" @@ -3991,7 +3459,6 @@ dev = [ { name = "markdown-exec", extra = ["ansi"] }, { name = "mike" }, { name = "mkdocs" }, - { name = "mkdocs-jupyter" }, { name = "mkdocs-material", extra = ["imaging"] }, { name = "mkdocs-redirects" }, { name = "mkdocstrings" }, @@ -4022,7 +3489,6 @@ docs = [ { name = "markdown-exec", extra = ["ansi"] }, { name = "mike" }, { name = "mkdocs" }, - { name = "mkdocs-jupyter" }, { name = "mkdocs-material", extra = ["imaging"] }, { name = "mkdocs-redirects" }, { name = "mkdocstrings" }, @@ -4099,7 +3565,6 @@ dev = [ { name = "markdown-exec", extras = ["ansi"], specifier = "==1.12.1" }, { name = "mike", specifier = "==2.2.0" }, { name = "mkdocs", specifier = "==1.6.1" }, - { name = "mkdocs-jupyter", specifier = "==0.26.3" }, { name = "mkdocs-material", extras = ["imaging"], specifier = "==9.7.6" }, { name = "mkdocs-redirects", specifier = "==1.2.3" }, { name = "mkdocstrings", specifier = "==1.0.4" }, @@ -4130,7 +3595,6 @@ docs = [ { name = "markdown-exec", extras = ["ansi"], specifier = "==1.12.1" }, { name = "mike", specifier = "==2.2.0" }, { name = "mkdocs", specifier = "==1.6.1" }, - { name = "mkdocs-jupyter", specifier = "==0.26.3" }, { name = "mkdocs-material", extras = ["imaging"], specifier = "==9.7.6" }, { name = "mkdocs-redirects", specifier = "==1.2.3" }, { name = "mkdocstrings", specifier = "==1.0.4" }, From 1e0ba06eeecb9ced2cb2d08f13fc90a53bf8cfb8 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 10:22:38 +0200 Subject: [PATCH 07/13] docs: shorten custom dtype example title to "Custom Data Type" Co-Authored-By: Claude Fable 5 --- examples/custom_dtype/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom_dtype/README.md b/examples/custom_dtype/README.md index d51c2b514a..266f398ca8 100644 --- a/examples/custom_dtype/README.md +++ b/examples/custom_dtype/README.md @@ -1,4 +1,4 @@ -# Custom Data Type Example +# Custom Data Type This example demonstrates how to extend Zarr Python by defining a new data type. From a2b0500f991f284978a6a58ff742e60faa97f290 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 10:37:34 +0200 Subject: [PATCH 08/13] docs: restructure API reference nav to distinguish classes from modules The API nav was a flat list whose labels came from each page's first mkdocstrings heading, mixing classes (Array), modules (codecs), and function groups (create) with no visual distinction, plus accidental labels like a title-cased Cpu, two literal Index entries, and an API section nested under API Reference. Group the nav into Classes / Functions / Modules with explicit titles: classes as zarr.Array and zarr.Group, function pages as Creating/Opening/ Saving/Loading, and modules by their dotted import path (zarr.storage, zarr.abc.store, ...), so the naming convention itself distinguishes the kinds. Also give the four subpackage index pages consistent titles. Page URLs are unchanged. Co-Authored-By: Claude Fable 5 --- docs/api/zarr/abc/index.md | 18 +++++--- docs/api/zarr/api/index.md | 4 +- docs/api/zarr/buffer/index.md | 4 ++ docs/api/zarr/testing/index.md | 14 ++++--- mkdocs.yml | 77 ++++++++++++++++++---------------- 5 files changed, 67 insertions(+), 50 deletions(-) diff --git a/docs/api/zarr/abc/index.md b/docs/api/zarr/abc/index.md index 7c2fb2ef13..7e15cb2a51 100644 --- a/docs/api/zarr/abc/index.md +++ b/docs/api/zarr/abc/index.md @@ -1,7 +1,13 @@ -## Abstract base classes +--- +title: zarr.abc +--- -- **[buffer](./buffer.md)** - Providing access to underlying memory via [buffers](https://docs.python.org/3/c-api/buffer.html) -- **[codec](./codec.md)** - Expressing [zarr codecs](https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#chunk-encoding) -- **[metadata](./metadata.md)** - Creating metadata classes compatible with the Zarr API -- **[numcodec](./numcodec.md)** - Protocols and classes for modeling codec interface used by numcodecs -- **[store](./store.md)** - ABC for implementing Zarr stores and managing getting and setting bytes in a store \ No newline at end of file +# zarr.abc + +Abstract base classes for extending Zarr-Python. + +- **[zarr.abc.buffer](./buffer.md)** - Providing access to underlying memory via [buffers](https://docs.python.org/3/c-api/buffer.html) +- **[zarr.abc.codec](./codec.md)** - Expressing [zarr codecs](https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#chunk-encoding) +- **[zarr.abc.metadata](./metadata.md)** - Creating metadata classes compatible with the Zarr API +- **[zarr.abc.numcodec](./numcodec.md)** - Protocols and classes for modeling codec interface used by numcodecs +- **[zarr.abc.store](./store.md)** - ABC for implementing Zarr stores and managing getting and setting bytes in a store diff --git a/docs/api/zarr/api/index.md b/docs/api/zarr/api/index.md index 75b4fff62b..7fac5e766a 100644 --- a/docs/api/zarr/api/index.md +++ b/docs/api/zarr/api/index.md @@ -1,5 +1,7 @@ --- -title: API +title: zarr.api --- +# zarr.api + Zarr provides both an [async](./asynchronous.md) and a [sync](./synchronous.md) API. See those pages for more details. diff --git a/docs/api/zarr/buffer/index.md b/docs/api/zarr/buffer/index.md index 0b303781e1..ebbb9e1c99 100644 --- a/docs/api/zarr/buffer/index.md +++ b/docs/api/zarr/buffer/index.md @@ -1,3 +1,7 @@ +--- +title: zarr.buffer +--- + Zarr provides buffer classes for both the [cpu](./cpu.md) and [gpu](./gpu.md). Generic buffer functionality is also detailed below. ::: zarr.buffer diff --git a/docs/api/zarr/testing/index.md b/docs/api/zarr/testing/index.md index ab5dd1daa0..2b48ad349f 100644 --- a/docs/api/zarr/testing/index.md +++ b/docs/api/zarr/testing/index.md @@ -1,11 +1,13 @@ --- -title: testing +title: zarr.testing --- +# zarr.testing + See the following sub-modules: -- [buffer](./buffer.md) -- [stateful](./stateful.md) -- [store](./store.md) -- [strategies](./strategies.md) -- [utils](./utils.md) +- [zarr.testing.buffer](./buffer.md) +- [zarr.testing.stateful](./stateful.md) +- [zarr.testing.store](./store.md) +- [zarr.testing.strategies](./strategies.md) +- [zarr.testing.utils](./utils.md) diff --git a/mkdocs.yml b/mkdocs.yml index a4c37a2c17..e768985dac 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,43 +33,46 @@ nav: - user-guide/examples/rectilinear_chunks.md - API Reference: - api/zarr/index.md - - api/zarr/array.md - - api/zarr/group.md - - api/zarr/create.md - - api/zarr/dtype.md - - api/zarr/load.md - - api/zarr/open.md - - api/zarr/save.md - - api/zarr/codecs.md - - api/zarr/codecs/numcodecs.md - - api/zarr/config.md - - api/zarr/errors.md - - api/zarr/metadata.md - - api/zarr/registry.md - - api/zarr/storage.md - - api/zarr/experimental.md - - ABC: - - api/zarr/abc/index.md - - api/zarr/abc/buffer.md - - api/zarr/abc/codec.md - - api/zarr/abc/numcodec.md - - api/zarr/abc/metadata.md - - api/zarr/abc/store.md - - API: - - api/zarr/api/index.md - - api/zarr/api/asynchronous.md - - api/zarr/api/synchronous.md - - Buffer: - - api/zarr/buffer/index.md - - api/zarr/buffer/cpu.md - - api/zarr/buffer/gpu.md - - Testing: - - api/zarr/testing/index.md - - api/zarr/testing/buffer.md - - api/zarr/testing/stateful.md - - api/zarr/testing/store.md - - api/zarr/testing/strategies.md - - api/zarr/testing/utils.md + - Classes: + - zarr.Array: api/zarr/array.md + - zarr.Group: api/zarr/group.md + - Functions: + - Creating: api/zarr/create.md + - Opening: api/zarr/open.md + - Saving: api/zarr/save.md + - Loading: api/zarr/load.md + - Modules: + - zarr.abc: + - api/zarr/abc/index.md + - zarr.abc.buffer: api/zarr/abc/buffer.md + - zarr.abc.codec: api/zarr/abc/codec.md + - zarr.abc.metadata: api/zarr/abc/metadata.md + - zarr.abc.numcodec: api/zarr/abc/numcodec.md + - zarr.abc.store: api/zarr/abc/store.md + - zarr.api: + - api/zarr/api/index.md + - zarr.api.asynchronous: api/zarr/api/asynchronous.md + - zarr.api.synchronous: api/zarr/api/synchronous.md + - zarr.buffer: + - api/zarr/buffer/index.md + - zarr.buffer.cpu: api/zarr/buffer/cpu.md + - zarr.buffer.gpu: api/zarr/buffer/gpu.md + - zarr.codecs: api/zarr/codecs.md + - zarr.codecs.numcodecs: api/zarr/codecs/numcodecs.md + - zarr.config: api/zarr/config.md + - zarr.dtype: api/zarr/dtype.md + - zarr.errors: api/zarr/errors.md + - zarr.experimental: api/zarr/experimental.md + - zarr.metadata: api/zarr/metadata.md + - zarr.registry: api/zarr/registry.md + - zarr.storage: api/zarr/storage.md + - zarr.testing: + - api/zarr/testing/index.md + - zarr.testing.buffer: api/zarr/testing/buffer.md + - zarr.testing.stateful: api/zarr/testing/stateful.md + - zarr.testing.store: api/zarr/testing/store.md + - zarr.testing.strategies: api/zarr/testing/strategies.md + - zarr.testing.utils: api/zarr/testing/utils.md - release-notes.md - contributing.md hooks: From c808ff328d69554a82f65d68e850aa984a8be452 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 10:54:34 +0200 Subject: [PATCH 09/13] docs: flatten API reference nav with kind annotations Users browsing the API reference don't know in advance whether the thing they want is a class, function, or module, so grouping the nav by kind made them guess. Flatten the list back and annotate each entry with its kind instead: zarr.Array (class), Creating (functions), zarr.storage (module). Nesting is kept only where it means containment (the abc, api, buffer, and testing subpackages); their children are unannotated since context makes them modules. Co-Authored-By: Claude Fable 5 --- mkdocs.yml | 77 ++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index e768985dac..94bee32135 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,46 +33,43 @@ nav: - user-guide/examples/rectilinear_chunks.md - API Reference: - api/zarr/index.md - - Classes: - - zarr.Array: api/zarr/array.md - - zarr.Group: api/zarr/group.md - - Functions: - - Creating: api/zarr/create.md - - Opening: api/zarr/open.md - - Saving: api/zarr/save.md - - Loading: api/zarr/load.md - - Modules: - - zarr.abc: - - api/zarr/abc/index.md - - zarr.abc.buffer: api/zarr/abc/buffer.md - - zarr.abc.codec: api/zarr/abc/codec.md - - zarr.abc.metadata: api/zarr/abc/metadata.md - - zarr.abc.numcodec: api/zarr/abc/numcodec.md - - zarr.abc.store: api/zarr/abc/store.md - - zarr.api: - - api/zarr/api/index.md - - zarr.api.asynchronous: api/zarr/api/asynchronous.md - - zarr.api.synchronous: api/zarr/api/synchronous.md - - zarr.buffer: - - api/zarr/buffer/index.md - - zarr.buffer.cpu: api/zarr/buffer/cpu.md - - zarr.buffer.gpu: api/zarr/buffer/gpu.md - - zarr.codecs: api/zarr/codecs.md - - zarr.codecs.numcodecs: api/zarr/codecs/numcodecs.md - - zarr.config: api/zarr/config.md - - zarr.dtype: api/zarr/dtype.md - - zarr.errors: api/zarr/errors.md - - zarr.experimental: api/zarr/experimental.md - - zarr.metadata: api/zarr/metadata.md - - zarr.registry: api/zarr/registry.md - - zarr.storage: api/zarr/storage.md - - zarr.testing: - - api/zarr/testing/index.md - - zarr.testing.buffer: api/zarr/testing/buffer.md - - zarr.testing.stateful: api/zarr/testing/stateful.md - - zarr.testing.store: api/zarr/testing/store.md - - zarr.testing.strategies: api/zarr/testing/strategies.md - - zarr.testing.utils: api/zarr/testing/utils.md + - zarr.Array (class): api/zarr/array.md + - zarr.Group (class): api/zarr/group.md + - Creating (functions): api/zarr/create.md + - Opening (functions): api/zarr/open.md + - Saving (functions): api/zarr/save.md + - Loading (functions): api/zarr/load.md + - zarr.abc (module): + - api/zarr/abc/index.md + - zarr.abc.buffer: api/zarr/abc/buffer.md + - zarr.abc.codec: api/zarr/abc/codec.md + - zarr.abc.metadata: api/zarr/abc/metadata.md + - zarr.abc.numcodec: api/zarr/abc/numcodec.md + - zarr.abc.store: api/zarr/abc/store.md + - zarr.api (module): + - api/zarr/api/index.md + - zarr.api.asynchronous: api/zarr/api/asynchronous.md + - zarr.api.synchronous: api/zarr/api/synchronous.md + - zarr.buffer (module): + - api/zarr/buffer/index.md + - zarr.buffer.cpu: api/zarr/buffer/cpu.md + - zarr.buffer.gpu: api/zarr/buffer/gpu.md + - zarr.codecs (module): api/zarr/codecs.md + - zarr.codecs.numcodecs (module): api/zarr/codecs/numcodecs.md + - zarr.config (module): api/zarr/config.md + - zarr.dtype (module): api/zarr/dtype.md + - zarr.errors (module): api/zarr/errors.md + - zarr.experimental (module): api/zarr/experimental.md + - zarr.metadata (module): api/zarr/metadata.md + - zarr.registry (module): api/zarr/registry.md + - zarr.storage (module): api/zarr/storage.md + - zarr.testing (module): + - api/zarr/testing/index.md + - zarr.testing.buffer: api/zarr/testing/buffer.md + - zarr.testing.stateful: api/zarr/testing/stateful.md + - zarr.testing.store: api/zarr/testing/store.md + - zarr.testing.strategies: api/zarr/testing/strategies.md + - zarr.testing.utils: api/zarr/testing/utils.md - release-notes.md - contributing.md hooks: From f1d3eb59aeffe764f3cafbe919e2a62db23512f7 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 10:59:10 +0200 Subject: [PATCH 10/13] docs: use bare function-page names from main in the API nav create/open/save/load, as on main, rather than invented verb labels; the (functions) annotation carries the kind. Co-Authored-By: Claude Fable 5 --- mkdocs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 94bee32135..21445767c3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,10 +35,10 @@ nav: - api/zarr/index.md - zarr.Array (class): api/zarr/array.md - zarr.Group (class): api/zarr/group.md - - Creating (functions): api/zarr/create.md - - Opening (functions): api/zarr/open.md - - Saving (functions): api/zarr/save.md - - Loading (functions): api/zarr/load.md + - create (functions): api/zarr/create.md + - open (functions): api/zarr/open.md + - save (functions): api/zarr/save.md + - load (functions): api/zarr/load.md - zarr.abc (module): - api/zarr/abc/index.md - zarr.abc.buffer: api/zarr/abc/buffer.md From 8f51d57121e7d6084d76350c60ec01554bb7770f Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 9 Jul 2026 11:02:59 +0200 Subject: [PATCH 11/13] docs: render API nav identifiers in monospace Material passes nav titles through as HTML, so wrap the identifier part of each API reference nav label in , keeping the (class)/(functions)/ (module) annotations in regular type. Verified the HTML is not escaped in the sidebar, is stripped from the browser , and behaves in search like any backticked heading. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --- mkdocs.yml | 66 +++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 21445767c3..09215b7190 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,43 +33,43 @@ nav: - user-guide/examples/rectilinear_chunks.md - API Reference: - api/zarr/index.md - - zarr.Array (class): api/zarr/array.md - - zarr.Group (class): api/zarr/group.md - - create (functions): api/zarr/create.md - - open (functions): api/zarr/open.md - - save (functions): api/zarr/save.md - - load (functions): api/zarr/load.md - - zarr.abc (module): + - "<code>zarr.Array</code> (class)": api/zarr/array.md + - "<code>zarr.Group</code> (class)": api/zarr/group.md + - "<code>create</code> (functions)": api/zarr/create.md + - "<code>open</code> (functions)": api/zarr/open.md + - "<code>save</code> (functions)": api/zarr/save.md + - "<code>load</code> (functions)": api/zarr/load.md + - "<code>zarr.abc</code> (module)": - api/zarr/abc/index.md - - zarr.abc.buffer: api/zarr/abc/buffer.md - - zarr.abc.codec: api/zarr/abc/codec.md - - zarr.abc.metadata: api/zarr/abc/metadata.md - - zarr.abc.numcodec: api/zarr/abc/numcodec.md - - zarr.abc.store: api/zarr/abc/store.md - - zarr.api (module): + - "<code>zarr.abc.buffer</code>": api/zarr/abc/buffer.md + - "<code>zarr.abc.codec</code>": api/zarr/abc/codec.md + - "<code>zarr.abc.metadata</code>": api/zarr/abc/metadata.md + - "<code>zarr.abc.numcodec</code>": api/zarr/abc/numcodec.md + - "<code>zarr.abc.store</code>": api/zarr/abc/store.md + - "<code>zarr.api</code> (module)": - api/zarr/api/index.md - - zarr.api.asynchronous: api/zarr/api/asynchronous.md - - zarr.api.synchronous: api/zarr/api/synchronous.md - - zarr.buffer (module): + - "<code>zarr.api.asynchronous</code>": api/zarr/api/asynchronous.md + - "<code>zarr.api.synchronous</code>": api/zarr/api/synchronous.md + - "<code>zarr.buffer</code> (module)": - api/zarr/buffer/index.md - - zarr.buffer.cpu: api/zarr/buffer/cpu.md - - zarr.buffer.gpu: api/zarr/buffer/gpu.md - - zarr.codecs (module): api/zarr/codecs.md - - zarr.codecs.numcodecs (module): api/zarr/codecs/numcodecs.md - - zarr.config (module): api/zarr/config.md - - zarr.dtype (module): api/zarr/dtype.md - - zarr.errors (module): api/zarr/errors.md - - zarr.experimental (module): api/zarr/experimental.md - - zarr.metadata (module): api/zarr/metadata.md - - zarr.registry (module): api/zarr/registry.md - - zarr.storage (module): api/zarr/storage.md - - zarr.testing (module): + - "<code>zarr.buffer.cpu</code>": api/zarr/buffer/cpu.md + - "<code>zarr.buffer.gpu</code>": api/zarr/buffer/gpu.md + - "<code>zarr.codecs</code> (module)": api/zarr/codecs.md + - "<code>zarr.codecs.numcodecs</code> (module)": api/zarr/codecs/numcodecs.md + - "<code>zarr.config</code> (module)": api/zarr/config.md + - "<code>zarr.dtype</code> (module)": api/zarr/dtype.md + - "<code>zarr.errors</code> (module)": api/zarr/errors.md + - "<code>zarr.experimental</code> (module)": api/zarr/experimental.md + - "<code>zarr.metadata</code> (module)": api/zarr/metadata.md + - "<code>zarr.registry</code> (module)": api/zarr/registry.md + - "<code>zarr.storage</code> (module)": api/zarr/storage.md + - "<code>zarr.testing</code> (module)": - api/zarr/testing/index.md - - zarr.testing.buffer: api/zarr/testing/buffer.md - - zarr.testing.stateful: api/zarr/testing/stateful.md - - zarr.testing.store: api/zarr/testing/store.md - - zarr.testing.strategies: api/zarr/testing/strategies.md - - zarr.testing.utils: api/zarr/testing/utils.md + - "<code>zarr.testing.buffer</code>": api/zarr/testing/buffer.md + - "<code>zarr.testing.stateful</code>": api/zarr/testing/stateful.md + - "<code>zarr.testing.store</code>": api/zarr/testing/store.md + - "<code>zarr.testing.strategies</code>": api/zarr/testing/strategies.md + - "<code>zarr.testing.utils</code>": api/zarr/testing/utils.md - release-notes.md - contributing.md hooks: From 2ca7e38a5b0db7e926375f5a126e3605a087473b Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett <davis.v.bennett@gmail.com> Date: Thu, 9 Jul 2026 11:21:57 +0200 Subject: [PATCH 12/13] docs: one API nav entry per function, mirroring the flat zarr namespace The create/open/save/load pages grouped functions by verb, an organization that doesn't exist in the codebase -- all of these are top-level names in the flat zarr namespace. Replace them with one page and one nav entry per function (zarr.create_array, zarr.open_group, ...), alphabetized case- insensitively alongside the classes and modules, so zarr.Array (class) sits next to zarr.array (function). This also adds previously undocumented public functions to the API reference: zarr.consolidate_metadata and zarr.print_debug_info. The unimplemented copy/copy_all/copy_store stubs and the deprecated zarr.tree are deliberately excluded. Old create/open/save/load URLs redirect to representative function pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --- docs/api/zarr/create.md | 19 ---------- docs/api/zarr/functions/array.md | 5 +++ .../zarr/functions/consolidate_metadata.md | 5 +++ docs/api/zarr/functions/create.md | 5 +++ docs/api/zarr/functions/create_array.md | 5 +++ docs/api/zarr/functions/create_group.md | 5 +++ docs/api/zarr/functions/create_hierarchy.md | 5 +++ docs/api/zarr/functions/empty.md | 5 +++ docs/api/zarr/functions/empty_like.md | 5 +++ docs/api/zarr/functions/from_array.md | 5 +++ docs/api/zarr/functions/full.md | 5 +++ docs/api/zarr/functions/full_like.md | 5 +++ docs/api/zarr/functions/group.md | 5 +++ docs/api/zarr/{ => functions}/load.md | 2 +- docs/api/zarr/functions/ones.md | 5 +++ docs/api/zarr/functions/ones_like.md | 5 +++ docs/api/zarr/functions/open.md | 5 +++ docs/api/zarr/functions/open_array.md | 5 +++ docs/api/zarr/functions/open_consolidated.md | 5 +++ docs/api/zarr/functions/open_group.md | 5 +++ docs/api/zarr/functions/open_like.md | 5 +++ docs/api/zarr/functions/print_debug_info.md | 5 +++ docs/api/zarr/functions/save.md | 5 +++ docs/api/zarr/functions/save_array.md | 5 +++ docs/api/zarr/functions/save_group.md | 5 +++ docs/api/zarr/functions/zeros.md | 5 +++ docs/api/zarr/functions/zeros_like.md | 5 +++ docs/api/zarr/index.md | 8 ++-- docs/api/zarr/open.md | 9 ----- docs/api/zarr/save.md | 7 ---- docs/user-guide/arrays.md | 2 +- mkdocs.yml | 38 ++++++++++++++++--- 32 files changed, 163 insertions(+), 47 deletions(-) delete mode 100644 docs/api/zarr/create.md create mode 100644 docs/api/zarr/functions/array.md create mode 100644 docs/api/zarr/functions/consolidate_metadata.md create mode 100644 docs/api/zarr/functions/create.md create mode 100644 docs/api/zarr/functions/create_array.md create mode 100644 docs/api/zarr/functions/create_group.md create mode 100644 docs/api/zarr/functions/create_hierarchy.md create mode 100644 docs/api/zarr/functions/empty.md create mode 100644 docs/api/zarr/functions/empty_like.md create mode 100644 docs/api/zarr/functions/from_array.md create mode 100644 docs/api/zarr/functions/full.md create mode 100644 docs/api/zarr/functions/full_like.md create mode 100644 docs/api/zarr/functions/group.md rename docs/api/zarr/{ => functions}/load.md (57%) create mode 100644 docs/api/zarr/functions/ones.md create mode 100644 docs/api/zarr/functions/ones_like.md create mode 100644 docs/api/zarr/functions/open.md create mode 100644 docs/api/zarr/functions/open_array.md create mode 100644 docs/api/zarr/functions/open_consolidated.md create mode 100644 docs/api/zarr/functions/open_group.md create mode 100644 docs/api/zarr/functions/open_like.md create mode 100644 docs/api/zarr/functions/print_debug_info.md create mode 100644 docs/api/zarr/functions/save.md create mode 100644 docs/api/zarr/functions/save_array.md create mode 100644 docs/api/zarr/functions/save_group.md create mode 100644 docs/api/zarr/functions/zeros.md create mode 100644 docs/api/zarr/functions/zeros_like.md delete mode 100644 docs/api/zarr/open.md delete mode 100644 docs/api/zarr/save.md diff --git a/docs/api/zarr/create.md b/docs/api/zarr/create.md deleted file mode 100644 index 971e9c293c..0000000000 --- a/docs/api/zarr/create.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: create ---- - -::: zarr.array -::: zarr.create -::: zarr.create_array -::: zarr.create_group -::: zarr.create_hierarchy -::: zarr.empty -::: zarr.empty_like -::: zarr.full -::: zarr.full_like -::: zarr.from_array -::: zarr.group -::: zarr.ones -::: zarr.ones_like -::: zarr.zeros -::: zarr.zeros_like diff --git a/docs/api/zarr/functions/array.md b/docs/api/zarr/functions/array.md new file mode 100644 index 0000000000..ff7242005c --- /dev/null +++ b/docs/api/zarr/functions/array.md @@ -0,0 +1,5 @@ +--- +title: zarr.array +--- + +::: zarr.array diff --git a/docs/api/zarr/functions/consolidate_metadata.md b/docs/api/zarr/functions/consolidate_metadata.md new file mode 100644 index 0000000000..946531f028 --- /dev/null +++ b/docs/api/zarr/functions/consolidate_metadata.md @@ -0,0 +1,5 @@ +--- +title: zarr.consolidate_metadata +--- + +::: zarr.consolidate_metadata diff --git a/docs/api/zarr/functions/create.md b/docs/api/zarr/functions/create.md new file mode 100644 index 0000000000..b43094eaba --- /dev/null +++ b/docs/api/zarr/functions/create.md @@ -0,0 +1,5 @@ +--- +title: zarr.create +--- + +::: zarr.create diff --git a/docs/api/zarr/functions/create_array.md b/docs/api/zarr/functions/create_array.md new file mode 100644 index 0000000000..a9f4a24bd0 --- /dev/null +++ b/docs/api/zarr/functions/create_array.md @@ -0,0 +1,5 @@ +--- +title: zarr.create_array +--- + +::: zarr.create_array diff --git a/docs/api/zarr/functions/create_group.md b/docs/api/zarr/functions/create_group.md new file mode 100644 index 0000000000..50beb0674c --- /dev/null +++ b/docs/api/zarr/functions/create_group.md @@ -0,0 +1,5 @@ +--- +title: zarr.create_group +--- + +::: zarr.create_group diff --git a/docs/api/zarr/functions/create_hierarchy.md b/docs/api/zarr/functions/create_hierarchy.md new file mode 100644 index 0000000000..38938ffee2 --- /dev/null +++ b/docs/api/zarr/functions/create_hierarchy.md @@ -0,0 +1,5 @@ +--- +title: zarr.create_hierarchy +--- + +::: zarr.create_hierarchy diff --git a/docs/api/zarr/functions/empty.md b/docs/api/zarr/functions/empty.md new file mode 100644 index 0000000000..aff67bb9ed --- /dev/null +++ b/docs/api/zarr/functions/empty.md @@ -0,0 +1,5 @@ +--- +title: zarr.empty +--- + +::: zarr.empty diff --git a/docs/api/zarr/functions/empty_like.md b/docs/api/zarr/functions/empty_like.md new file mode 100644 index 0000000000..9e2fbd26a5 --- /dev/null +++ b/docs/api/zarr/functions/empty_like.md @@ -0,0 +1,5 @@ +--- +title: zarr.empty_like +--- + +::: zarr.empty_like diff --git a/docs/api/zarr/functions/from_array.md b/docs/api/zarr/functions/from_array.md new file mode 100644 index 0000000000..7ab8179b05 --- /dev/null +++ b/docs/api/zarr/functions/from_array.md @@ -0,0 +1,5 @@ +--- +title: zarr.from_array +--- + +::: zarr.from_array diff --git a/docs/api/zarr/functions/full.md b/docs/api/zarr/functions/full.md new file mode 100644 index 0000000000..d6c60de2d5 --- /dev/null +++ b/docs/api/zarr/functions/full.md @@ -0,0 +1,5 @@ +--- +title: zarr.full +--- + +::: zarr.full diff --git a/docs/api/zarr/functions/full_like.md b/docs/api/zarr/functions/full_like.md new file mode 100644 index 0000000000..eb5c162f76 --- /dev/null +++ b/docs/api/zarr/functions/full_like.md @@ -0,0 +1,5 @@ +--- +title: zarr.full_like +--- + +::: zarr.full_like diff --git a/docs/api/zarr/functions/group.md b/docs/api/zarr/functions/group.md new file mode 100644 index 0000000000..3048218f6b --- /dev/null +++ b/docs/api/zarr/functions/group.md @@ -0,0 +1,5 @@ +--- +title: zarr.group +--- + +::: zarr.group diff --git a/docs/api/zarr/load.md b/docs/api/zarr/functions/load.md similarity index 57% rename from docs/api/zarr/load.md rename to docs/api/zarr/functions/load.md index d6463ca976..aa004076ab 100644 --- a/docs/api/zarr/load.md +++ b/docs/api/zarr/functions/load.md @@ -1,5 +1,5 @@ --- -title: load +title: zarr.load --- ::: zarr.load diff --git a/docs/api/zarr/functions/ones.md b/docs/api/zarr/functions/ones.md new file mode 100644 index 0000000000..b7757da1bc --- /dev/null +++ b/docs/api/zarr/functions/ones.md @@ -0,0 +1,5 @@ +--- +title: zarr.ones +--- + +::: zarr.ones diff --git a/docs/api/zarr/functions/ones_like.md b/docs/api/zarr/functions/ones_like.md new file mode 100644 index 0000000000..cffccb10ef --- /dev/null +++ b/docs/api/zarr/functions/ones_like.md @@ -0,0 +1,5 @@ +--- +title: zarr.ones_like +--- + +::: zarr.ones_like diff --git a/docs/api/zarr/functions/open.md b/docs/api/zarr/functions/open.md new file mode 100644 index 0000000000..3d75977395 --- /dev/null +++ b/docs/api/zarr/functions/open.md @@ -0,0 +1,5 @@ +--- +title: zarr.open +--- + +::: zarr.open diff --git a/docs/api/zarr/functions/open_array.md b/docs/api/zarr/functions/open_array.md new file mode 100644 index 0000000000..f40da1bd5d --- /dev/null +++ b/docs/api/zarr/functions/open_array.md @@ -0,0 +1,5 @@ +--- +title: zarr.open_array +--- + +::: zarr.open_array diff --git a/docs/api/zarr/functions/open_consolidated.md b/docs/api/zarr/functions/open_consolidated.md new file mode 100644 index 0000000000..de71cf7662 --- /dev/null +++ b/docs/api/zarr/functions/open_consolidated.md @@ -0,0 +1,5 @@ +--- +title: zarr.open_consolidated +--- + +::: zarr.open_consolidated diff --git a/docs/api/zarr/functions/open_group.md b/docs/api/zarr/functions/open_group.md new file mode 100644 index 0000000000..4944e94e06 --- /dev/null +++ b/docs/api/zarr/functions/open_group.md @@ -0,0 +1,5 @@ +--- +title: zarr.open_group +--- + +::: zarr.open_group diff --git a/docs/api/zarr/functions/open_like.md b/docs/api/zarr/functions/open_like.md new file mode 100644 index 0000000000..1aea075a81 --- /dev/null +++ b/docs/api/zarr/functions/open_like.md @@ -0,0 +1,5 @@ +--- +title: zarr.open_like +--- + +::: zarr.open_like diff --git a/docs/api/zarr/functions/print_debug_info.md b/docs/api/zarr/functions/print_debug_info.md new file mode 100644 index 0000000000..c98329f893 --- /dev/null +++ b/docs/api/zarr/functions/print_debug_info.md @@ -0,0 +1,5 @@ +--- +title: zarr.print_debug_info +--- + +::: zarr.print_debug_info diff --git a/docs/api/zarr/functions/save.md b/docs/api/zarr/functions/save.md new file mode 100644 index 0000000000..6c8eae410f --- /dev/null +++ b/docs/api/zarr/functions/save.md @@ -0,0 +1,5 @@ +--- +title: zarr.save +--- + +::: zarr.save diff --git a/docs/api/zarr/functions/save_array.md b/docs/api/zarr/functions/save_array.md new file mode 100644 index 0000000000..58a6d5143d --- /dev/null +++ b/docs/api/zarr/functions/save_array.md @@ -0,0 +1,5 @@ +--- +title: zarr.save_array +--- + +::: zarr.save_array diff --git a/docs/api/zarr/functions/save_group.md b/docs/api/zarr/functions/save_group.md new file mode 100644 index 0000000000..ba66a70563 --- /dev/null +++ b/docs/api/zarr/functions/save_group.md @@ -0,0 +1,5 @@ +--- +title: zarr.save_group +--- + +::: zarr.save_group diff --git a/docs/api/zarr/functions/zeros.md b/docs/api/zarr/functions/zeros.md new file mode 100644 index 0000000000..d43e8d913b --- /dev/null +++ b/docs/api/zarr/functions/zeros.md @@ -0,0 +1,5 @@ +--- +title: zarr.zeros +--- + +::: zarr.zeros diff --git a/docs/api/zarr/functions/zeros_like.md b/docs/api/zarr/functions/zeros_like.md new file mode 100644 index 0000000000..5adf1a23b3 --- /dev/null +++ b/docs/api/zarr/functions/zeros_like.md @@ -0,0 +1,5 @@ +--- +title: zarr.zeros_like +--- + +::: zarr.zeros_like diff --git a/docs/api/zarr/index.md b/docs/api/zarr/index.md index 194edb7913..f691c4599a 100644 --- a/docs/api/zarr/index.md +++ b/docs/api/zarr/index.md @@ -14,13 +14,13 @@ Complete reference documentation for the Zarr-Python API. - **[Array](array.md)** - The main Zarr array class for N-dimensional data - **[Group](group.md)** - Hierarchical organization of arrays and subgroups -- **[Create](create.md)** - Functions for creating new arrays and groups -- **[Open](open.md)** - Opening existing Zarr stores and arrays +- **[create_array](functions/create_array.md)** and **[create_group](functions/create_group.md)** - Creating new arrays and groups +- **[open](functions/open.md)**, **[open_array](functions/open_array.md)**, and **[open_group](functions/open_group.md)** - Opening existing Zarr stores, arrays, and groups ### Data Operations -- **[Load](load.md)** - Loading data from Zarr stores -- **[Save](save.md)** - Saving data to Zarr format +- **[load](functions/load.md)** - Loading data from Zarr stores +- **[save](functions/save.md)** - Saving data to Zarr format ### Data Types and Configuration diff --git a/docs/api/zarr/open.md b/docs/api/zarr/open.md deleted file mode 100644 index c59f896129..0000000000 --- a/docs/api/zarr/open.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: open ---- - -::: zarr.open -::: zarr.open_array -::: zarr.open_consolidated -::: zarr.open_group -::: zarr.open_like diff --git a/docs/api/zarr/save.md b/docs/api/zarr/save.md deleted file mode 100644 index c611d10a4c..0000000000 --- a/docs/api/zarr/save.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: save ---- - -::: zarr.save -::: zarr.save_array -::: zarr.save_group diff --git a/docs/user-guide/arrays.md b/docs/user-guide/arrays.md index f459b2d38d..51b2fa1a17 100644 --- a/docs/user-guide/arrays.md +++ b/docs/user-guide/arrays.md @@ -28,7 +28,7 @@ See [Data types](data_types.md) for an in-depth look at the data types supported by Zarr, and [Chunk size and shape](performance.md#chunk-size-and-shape) in the performance guide for guidance on choosing chunk shapes. -See the [creation API documentation](../api/zarr/create.md) for more detailed information about +See the [`zarr.create_array`][] API documentation for more detailed information about creating arrays. ## Reading and writing data diff --git a/mkdocs.yml b/mkdocs.yml index 09215b7190..f6f3044569 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,12 +33,6 @@ nav: - user-guide/examples/rectilinear_chunks.md - API Reference: - api/zarr/index.md - - "<code>zarr.Array</code> (class)": api/zarr/array.md - - "<code>zarr.Group</code> (class)": api/zarr/group.md - - "<code>create</code> (functions)": api/zarr/create.md - - "<code>open</code> (functions)": api/zarr/open.md - - "<code>save</code> (functions)": api/zarr/save.md - - "<code>load</code> (functions)": api/zarr/load.md - "<code>zarr.abc</code> (module)": - api/zarr/abc/index.md - "<code>zarr.abc.buffer</code>": api/zarr/abc/buffer.md @@ -50,6 +44,8 @@ nav: - api/zarr/api/index.md - "<code>zarr.api.asynchronous</code>": api/zarr/api/asynchronous.md - "<code>zarr.api.synchronous</code>": api/zarr/api/synchronous.md + - "<code>zarr.Array</code> (class)": api/zarr/array.md + - "<code>zarr.array</code> (function)": api/zarr/functions/array.md - "<code>zarr.buffer</code> (module)": - api/zarr/buffer/index.md - "<code>zarr.buffer.cpu</code>": api/zarr/buffer/cpu.md @@ -57,11 +53,35 @@ nav: - "<code>zarr.codecs</code> (module)": api/zarr/codecs.md - "<code>zarr.codecs.numcodecs</code> (module)": api/zarr/codecs/numcodecs.md - "<code>zarr.config</code> (module)": api/zarr/config.md + - "<code>zarr.consolidate_metadata</code> (function)": api/zarr/functions/consolidate_metadata.md + - "<code>zarr.create</code> (function)": api/zarr/functions/create.md + - "<code>zarr.create_array</code> (function)": api/zarr/functions/create_array.md + - "<code>zarr.create_group</code> (function)": api/zarr/functions/create_group.md + - "<code>zarr.create_hierarchy</code> (function)": api/zarr/functions/create_hierarchy.md - "<code>zarr.dtype</code> (module)": api/zarr/dtype.md + - "<code>zarr.empty</code> (function)": api/zarr/functions/empty.md + - "<code>zarr.empty_like</code> (function)": api/zarr/functions/empty_like.md - "<code>zarr.errors</code> (module)": api/zarr/errors.md - "<code>zarr.experimental</code> (module)": api/zarr/experimental.md + - "<code>zarr.from_array</code> (function)": api/zarr/functions/from_array.md + - "<code>zarr.full</code> (function)": api/zarr/functions/full.md + - "<code>zarr.full_like</code> (function)": api/zarr/functions/full_like.md + - "<code>zarr.Group</code> (class)": api/zarr/group.md + - "<code>zarr.group</code> (function)": api/zarr/functions/group.md + - "<code>zarr.load</code> (function)": api/zarr/functions/load.md - "<code>zarr.metadata</code> (module)": api/zarr/metadata.md + - "<code>zarr.ones</code> (function)": api/zarr/functions/ones.md + - "<code>zarr.ones_like</code> (function)": api/zarr/functions/ones_like.md + - "<code>zarr.open</code> (function)": api/zarr/functions/open.md + - "<code>zarr.open_array</code> (function)": api/zarr/functions/open_array.md + - "<code>zarr.open_consolidated</code> (function)": api/zarr/functions/open_consolidated.md + - "<code>zarr.open_group</code> (function)": api/zarr/functions/open_group.md + - "<code>zarr.open_like</code> (function)": api/zarr/functions/open_like.md + - "<code>zarr.print_debug_info</code> (function)": api/zarr/functions/print_debug_info.md - "<code>zarr.registry</code> (module)": api/zarr/registry.md + - "<code>zarr.save</code> (function)": api/zarr/functions/save.md + - "<code>zarr.save_array</code> (function)": api/zarr/functions/save_array.md + - "<code>zarr.save_group</code> (function)": api/zarr/functions/save_group.md - "<code>zarr.storage</code> (module)": api/zarr/storage.md - "<code>zarr.testing</code> (module)": - api/zarr/testing/index.md @@ -70,6 +90,8 @@ nav: - "<code>zarr.testing.store</code>": api/zarr/testing/store.md - "<code>zarr.testing.strategies</code>": api/zarr/testing/strategies.md - "<code>zarr.testing.utils</code>": api/zarr/testing/utils.md + - "<code>zarr.zeros</code> (function)": api/zarr/functions/zeros.md + - "<code>zarr.zeros_like</code> (function)": api/zarr/functions/zeros_like.md - release-notes.md - contributing.md hooks: @@ -215,6 +237,10 @@ plugins: 'developers/index.html.md': 'contributing.md' 'developers/roadmap.html.md': 'https://zarr.readthedocs.io/en/v3.0.8/developers/roadmap.html' 'api.md': 'api/zarr/index.md' + 'api/zarr/create.md': 'api/zarr/functions/create.md' + 'api/zarr/open.md': 'api/zarr/functions/open.md' + 'api/zarr/save.md': 'api/zarr/functions/save.md' + 'api/zarr/load.md': 'api/zarr/functions/load.md' 'api/zarr/metadata/migrate_v3.md': 'api/zarr/metadata.md' # Based on https://github.com/developmentseed/titiler/blob/50934c929cca2fa8d3c408d239015f8da429c6a8/docs/mkdocs.yml#L115-L140 From a56048a91a471131f34d05a5cec1afa4f65d3f37 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett <davis.v.bennett@gmail.com> Date: Thu, 9 Jul 2026 11:29:36 +0200 Subject: [PATCH 13/13] docs: use mkdocstrings symbol badges for kind annotations in API nav The spelled-out (function)/(module)/(class) annotations made 8 of 41 monospace nav entries wrap to two lines. Replace them with the compact func/mod/class doc-symbol badges that mkdocstrings already renders in every page's table of contents, joined to the name with a non-breaking space so badge and name never separate. Verified in the rendered site: no wrapped entries, badge CSS loads globally, and function-page titles render as e.g. 'func zarr.open_group'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --- mkdocs.yml | 110 ++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index f6f3044569..46bfc1764c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,65 +33,65 @@ nav: - user-guide/examples/rectilinear_chunks.md - API Reference: - api/zarr/index.md - - "<code>zarr.abc</code> (module)": + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.abc</code>': - api/zarr/abc/index.md - - "<code>zarr.abc.buffer</code>": api/zarr/abc/buffer.md - - "<code>zarr.abc.codec</code>": api/zarr/abc/codec.md - - "<code>zarr.abc.metadata</code>": api/zarr/abc/metadata.md - - "<code>zarr.abc.numcodec</code>": api/zarr/abc/numcodec.md - - "<code>zarr.abc.store</code>": api/zarr/abc/store.md - - "<code>zarr.api</code> (module)": + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.abc.buffer</code>': api/zarr/abc/buffer.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.abc.codec</code>': api/zarr/abc/codec.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.abc.metadata</code>': api/zarr/abc/metadata.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.abc.numcodec</code>': api/zarr/abc/numcodec.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.abc.store</code>': api/zarr/abc/store.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.api</code>': - api/zarr/api/index.md - - "<code>zarr.api.asynchronous</code>": api/zarr/api/asynchronous.md - - "<code>zarr.api.synchronous</code>": api/zarr/api/synchronous.md - - "<code>zarr.Array</code> (class)": api/zarr/array.md - - "<code>zarr.array</code> (function)": api/zarr/functions/array.md - - "<code>zarr.buffer</code> (module)": + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.api.asynchronous</code>': api/zarr/api/asynchronous.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.api.synchronous</code>': api/zarr/api/synchronous.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-class"></code> <code>zarr.Array</code>': api/zarr/array.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.array</code>': api/zarr/functions/array.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.buffer</code>': - api/zarr/buffer/index.md - - "<code>zarr.buffer.cpu</code>": api/zarr/buffer/cpu.md - - "<code>zarr.buffer.gpu</code>": api/zarr/buffer/gpu.md - - "<code>zarr.codecs</code> (module)": api/zarr/codecs.md - - "<code>zarr.codecs.numcodecs</code> (module)": api/zarr/codecs/numcodecs.md - - "<code>zarr.config</code> (module)": api/zarr/config.md - - "<code>zarr.consolidate_metadata</code> (function)": api/zarr/functions/consolidate_metadata.md - - "<code>zarr.create</code> (function)": api/zarr/functions/create.md - - "<code>zarr.create_array</code> (function)": api/zarr/functions/create_array.md - - "<code>zarr.create_group</code> (function)": api/zarr/functions/create_group.md - - "<code>zarr.create_hierarchy</code> (function)": api/zarr/functions/create_hierarchy.md - - "<code>zarr.dtype</code> (module)": api/zarr/dtype.md - - "<code>zarr.empty</code> (function)": api/zarr/functions/empty.md - - "<code>zarr.empty_like</code> (function)": api/zarr/functions/empty_like.md - - "<code>zarr.errors</code> (module)": api/zarr/errors.md - - "<code>zarr.experimental</code> (module)": api/zarr/experimental.md - - "<code>zarr.from_array</code> (function)": api/zarr/functions/from_array.md - - "<code>zarr.full</code> (function)": api/zarr/functions/full.md - - "<code>zarr.full_like</code> (function)": api/zarr/functions/full_like.md - - "<code>zarr.Group</code> (class)": api/zarr/group.md - - "<code>zarr.group</code> (function)": api/zarr/functions/group.md - - "<code>zarr.load</code> (function)": api/zarr/functions/load.md - - "<code>zarr.metadata</code> (module)": api/zarr/metadata.md - - "<code>zarr.ones</code> (function)": api/zarr/functions/ones.md - - "<code>zarr.ones_like</code> (function)": api/zarr/functions/ones_like.md - - "<code>zarr.open</code> (function)": api/zarr/functions/open.md - - "<code>zarr.open_array</code> (function)": api/zarr/functions/open_array.md - - "<code>zarr.open_consolidated</code> (function)": api/zarr/functions/open_consolidated.md - - "<code>zarr.open_group</code> (function)": api/zarr/functions/open_group.md - - "<code>zarr.open_like</code> (function)": api/zarr/functions/open_like.md - - "<code>zarr.print_debug_info</code> (function)": api/zarr/functions/print_debug_info.md - - "<code>zarr.registry</code> (module)": api/zarr/registry.md - - "<code>zarr.save</code> (function)": api/zarr/functions/save.md - - "<code>zarr.save_array</code> (function)": api/zarr/functions/save_array.md - - "<code>zarr.save_group</code> (function)": api/zarr/functions/save_group.md - - "<code>zarr.storage</code> (module)": api/zarr/storage.md - - "<code>zarr.testing</code> (module)": + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.buffer.cpu</code>': api/zarr/buffer/cpu.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.buffer.gpu</code>': api/zarr/buffer/gpu.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.codecs</code>': api/zarr/codecs.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.codecs.numcodecs</code>': api/zarr/codecs/numcodecs.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.config</code>': api/zarr/config.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.consolidate_metadata</code>': api/zarr/functions/consolidate_metadata.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.create</code>': api/zarr/functions/create.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.create_array</code>': api/zarr/functions/create_array.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.create_group</code>': api/zarr/functions/create_group.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.create_hierarchy</code>': api/zarr/functions/create_hierarchy.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.dtype</code>': api/zarr/dtype.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.empty</code>': api/zarr/functions/empty.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.empty_like</code>': api/zarr/functions/empty_like.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.errors</code>': api/zarr/errors.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.experimental</code>': api/zarr/experimental.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.from_array</code>': api/zarr/functions/from_array.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.full</code>': api/zarr/functions/full.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.full_like</code>': api/zarr/functions/full_like.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-class"></code> <code>zarr.Group</code>': api/zarr/group.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.group</code>': api/zarr/functions/group.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.load</code>': api/zarr/functions/load.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.metadata</code>': api/zarr/metadata.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.ones</code>': api/zarr/functions/ones.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.ones_like</code>': api/zarr/functions/ones_like.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.open</code>': api/zarr/functions/open.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.open_array</code>': api/zarr/functions/open_array.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.open_consolidated</code>': api/zarr/functions/open_consolidated.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.open_group</code>': api/zarr/functions/open_group.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.open_like</code>': api/zarr/functions/open_like.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.print_debug_info</code>': api/zarr/functions/print_debug_info.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.registry</code>': api/zarr/registry.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.save</code>': api/zarr/functions/save.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.save_array</code>': api/zarr/functions/save_array.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.save_group</code>': api/zarr/functions/save_group.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.storage</code>': api/zarr/storage.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.testing</code>': - api/zarr/testing/index.md - - "<code>zarr.testing.buffer</code>": api/zarr/testing/buffer.md - - "<code>zarr.testing.stateful</code>": api/zarr/testing/stateful.md - - "<code>zarr.testing.store</code>": api/zarr/testing/store.md - - "<code>zarr.testing.strategies</code>": api/zarr/testing/strategies.md - - "<code>zarr.testing.utils</code>": api/zarr/testing/utils.md - - "<code>zarr.zeros</code> (function)": api/zarr/functions/zeros.md - - "<code>zarr.zeros_like</code> (function)": api/zarr/functions/zeros_like.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.testing.buffer</code>': api/zarr/testing/buffer.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.testing.stateful</code>': api/zarr/testing/stateful.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.testing.store</code>': api/zarr/testing/store.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.testing.strategies</code>': api/zarr/testing/strategies.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-module"></code> <code>zarr.testing.utils</code>': api/zarr/testing/utils.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.zeros</code>': api/zarr/functions/zeros.md + - '<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> <code>zarr.zeros_like</code>': api/zarr/functions/zeros_like.md - release-notes.md - contributing.md hooks: