Repository navigation
feat: URL pipeline core — URLPipeline, adapters, registry, zarr.open_url #4192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jhamman
wants to merge
21
commits into
zarr-developers:main
Choose a base branch
from
jhamman:feature/url-pipeline-core
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
20f2ac8
feat: url-pipeline core — parser, adapter ABC, registry, store hooks
jhamman a198fd6
Merge remote-tracking branch 'upstream/main' into feature/url-pipelin…
jhamman 581c534
polish: validate mode before pipeline resolution, document adapter au…
jhamman 3ed2bb8
fix: load URL adapter entry points outside the registry lock
jhamman 9bf86ce
fix: close the adapter's store when read-only conversion fails; docum…
jhamman c149961
fix: honor the pipeline-selected zarr format at every make_store_path…
jhamman 60f14a0
docs: fix wrapper example path handling; document review follow-ups
jhamman af289fa
Merge branch 'main' of github.com:zarr-developers/zarr-python into fe…
jhamman 03ab3b0
test: skip fsspec memory:// divergence test when fsspec lacks AsyncFi…
jhamman 169f9f4
Merge branch 'main' into feature/url-pipeline-core
d-v-b 103c87d
refactor(url-pipeline): resolve pipelines from a URLPipeline object, …
d-v-b 7268264
refactor(url-pipeline): make open_url open existing nodes only
d-v-b 2ec816c
refactor(url-pipeline): drop the string-routing leftovers from the re…
d-v-b 7cee87b
refactor(url-pipeline): resolve through URLPipeline.resolve; simplify…
d-v-b eed6fc7
Merge branch 'main' into feature/url-pipeline-core
d-v-b 68d2cba
Merge remote-tracking branch 'upstream/main' into feature/url-pipelin…
jhamman 101dd2a
Merge branch 'feature/url-pipeline-core' into feature/url-pipeline-co…
jhamman 61abcbd
test: skip the '|'-in-local-path test on Windows
jhamman a1af777
Merge remote-tracking branch 'upstream/main' into feature/url-pipelin…
jhamman 3ca3e61
refactor(url-pipeline): shrink the adapter API to an ABC plus StorePath
jhamman d534d31
Merge branch 'main' into feature/url-pipeline-core
jhamman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| Added core support for URL pipelines (https://github.com/jbms/url-pipeline): | ||
| `|`-chained URLs that address zarr data through nested storage layers, e.g. | ||
| `s3://bucket/data.zip|zip:|zarr3:`. A parsed `zarr.storage.URLPipeline` (built with | ||
| `URLPipeline.from_url`) can be passed to any function that accepts a `StoreLike`, and | ||
| the new `zarr.open_url(url, mode="r" | "r+")` opens the existing node a pipeline string | ||
| addresses without ever creating or overwriting anything. Adapters for the | ||
| sub-URLs after the first are provided by third-party packages (e.g. Icechunk) through | ||
| the `zarr.url_adapters` entry-point group and the single-method | ||
| `zarr.abc.url_pipeline.URLPipelineAdapter` interface, which receives a | ||
| `zarr.storage.PipelineSegment` and `zarr.storage.PipelineContext` and returns a | ||
| `zarr.storage.StorePath`; adapters are loaded lazily and individually, and | ||
| `zarr.registry.register_url_adapter` registers one without an entry point. A builtin | ||
| `zip:` adapter will follow separately. | ||
|
|
||
| Behavior notes: | ||
|
|
||
| - Plain strings are never interpreted as pipelines: `zarr.open("data|x.zarr")` still | ||
| addresses a local directory of that name, whatever adapters are installed. Only | ||
| `zarr.open_url` and `URLPipeline.from_url` read a string as a pipeline. | ||
| - A trailing `zarr2:`/`zarr3:` segment selects the zarr format of the open or create | ||
| call, and its body is the path of the node to open. A `zarr_format` argument that | ||
| conflicts with it raises `ValueError`; functions whose `zarr_format` defaults to 3 | ||
| (`zarr.create_array`, `Group.from_store`, `Group.open`, `Array.open`) need an explicit | ||
| `zarr_format=None` to defer to the pipeline. `Array.open` gains a `zarr_format` | ||
| parameter mirroring `Group.open`. | ||
| - Inside a pipeline, `memory:` and `file:` roots follow the URL pipeline spec's spelling | ||
| rules (`memory:` ≡ `memory:/` ≡ `memory://`; `file:` must carry an absolute path with | ||
| at most a `localhost` authority). Percent-escapes are not decoded, matching | ||
| `LocalStore`. A pipeline's `memory:` root is zarr's `ManagedMemoryStore`, which does | ||
| not share data with the fsspec in-memory filesystem a plain `memory://name` string | ||
| resolves to. | ||
| - Wrapper adapters can open a local *file* root only in mode `"r"` (via | ||
| `dataclasses.replace(context, mode="r").resolve_preceding()`); writing through a | ||
| container file is not yet supported. | ||
| - A `zarr.url_adapters` entry point whose scheme is already registered is ignored with a | ||
| `ZarrUserWarning`, as are duplicate entry-point names; an entry point that fails to | ||
| import raises `URLPipelineError` naming it, and stays discoverable for a retry. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| title: url_pipeline | ||
| --- | ||
|
|
||
| ::: zarr.abc.url_pipeline |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| title: zarr.open_url | ||
| --- | ||
|
|
||
| ::: zarr.open_url |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| """ | ||
| Abstract base class for URL pipeline adapters. | ||
|
|
||
| A URL pipeline is a `|`-separated chain of sub-URLs, read outer-to-inner, | ||
| as specified by https://github.com/jbms/url-pipeline. The first sub-URL (the | ||
| *root*) locates a resource using a conventional URL, and each subsequent | ||
| sub-URL names an *adapter* that reinterprets everything to its left: | ||
|
|
||
| s3://bucket/data.zip|zip:path/inside|zarr3: | ||
|
|
||
| Third-party packages provide adapters by subclassing | ||
| [`URLPipelineAdapter`][zarr.abc.url_pipeline.URLPipelineAdapter] and | ||
| registering the class under the `zarr.url_adapters` entry-point group, | ||
| using the URL scheme as the entry-point name. The values an adapter receives | ||
| and returns, [`PipelineSegment`][zarr.storage.PipelineSegment], | ||
| [`PipelineContext`][zarr.storage.PipelineContext] and | ||
| [`StorePath`][zarr.storage.StorePath], live in `zarr.storage`. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from abc import ABC, abstractmethod | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| if TYPE_CHECKING: | ||
| from zarr.storage import PipelineContext, PipelineSegment, StorePath | ||
|
|
||
| __all__ = ["URLPipelineAdapter"] | ||
|
|
||
|
|
||
| class URLPipelineAdapter(ABC): | ||
| """ | ||
| Handler for one URL pipeline scheme. | ||
|
|
||
| Subclasses implement a single classmethod, | ||
| [`open_pipeline_segment`][zarr.abc.url_pipeline.URLPipelineAdapter.open_pipeline_segment], | ||
| and are registered under the `zarr.url_adapters` entry-point group with | ||
| the URL scheme as the entry-point name: | ||
|
|
||
| [project.entry-points."zarr.url_adapters"] | ||
| mypackage.myscheme = "mypackage.zarr_adapter:MyAdapter" | ||
|
|
||
| Nonstandard schemes should be vendor-prefixed (`vendor.scheme`) per the | ||
| URL pipeline specification. | ||
|
|
||
| An adapter is used in two positions: | ||
|
|
||
| - as an *adapter segment*: `s3://bucket/repo|icechunk://tag.v1` — the | ||
| context carries the preceding sub-URLs; | ||
| - as a *root scheme*: `gh://org/repo` — `context.preceding` is empty. | ||
| """ | ||
|
|
||
| @classmethod | ||
| @abstractmethod | ||
| async def open_pipeline_segment( | ||
| cls, segment: PipelineSegment, context: PipelineContext | ||
| ) -> StorePath: | ||
| """ | ||
| Resolve `segment` (in the context of the pipeline to its left) | ||
| into a store and a residual path within that store. | ||
|
|
||
| The returned store must already be open and must honor | ||
| `context.read_only` (the resolver additionally enforces it by | ||
| downgrading — or rejecting — a writable store when the caller | ||
| required read-only). The path of the returned | ||
| [`StorePath`][zarr.storage.StorePath] is the location the pipeline | ||
| addresses inside the store; it is empty for the store root. | ||
|
|
||
| This coroutine runs on zarr's internal I/O event loop. It must not | ||
| block (do I/O through async APIs or a thread executor) and must not | ||
| call zarr's synchronous API (`zarr.open`, `Group.open`, or anything | ||
| else that uses `zarr.core.sync.sync`) — doing so raises | ||
| `SyncError`. To open the preceding pipeline, use | ||
| [`resolve_preceding`][zarr.storage.PipelineContext.resolve_preceding]. | ||
| """ | ||
| ... | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.