2
2
3
3
import pickle
4
4
from collections .abc import Iterable
5
- from typing import TYPE_CHECKING , Any
5
+ from typing import TYPE_CHECKING , Any , Mapping
6
6
from urllib .parse import urlparse
7
7
8
8
from zarr .abc .store import (
15
15
from zarr .core .buffer import Buffer
16
16
from zarr .core .buffer .core import BufferPrototype
17
17
18
+ from virtualizarr .manifests .array import ManifestArray
18
19
from virtualizarr .manifests .group import ManifestGroup
19
20
20
21
if TYPE_CHECKING :
27
28
28
29
__all__ = ["ManifestStore" ]
29
30
31
+
30
32
_ALLOWED_EXCEPTIONS : tuple [type [Exception ], ...] = (
31
33
FileNotFoundError ,
32
34
IsADirectoryError ,
39
41
40
42
from zarr .core .buffer import default_buffer_prototype
41
43
42
- from virtualizarr .manifests .group import ManifestArrayVariableMapping
43
44
from virtualizarr .vendor .zarr .metadata import dict_to_buffer
44
45
45
46
if TYPE_CHECKING :
@@ -59,20 +60,20 @@ class StoreRequest:
59
60
60
61
61
62
async def list_dir_from_manifest_arrays (
62
- manifest_arrays : ManifestArrayVariableMapping , prefix : str
63
+ arrays : Mapping [ str , ManifestArray ] , prefix : str
63
64
) -> AsyncGenerator [str ]:
64
65
"""Create the expected results for Zarr's `store.list_dir()` from an Xarray DataArrray or Dataset
65
66
66
67
Parameters
67
68
----------
68
- manifest_arrays : ManifestArrayVariableMapping
69
+ arrays : Mapping[str, ManifestArrays]
69
70
prefix : str
70
71
71
-
72
72
Returns
73
73
-------
74
74
AsyncIterator[str]
75
75
"""
76
+ # TODO shouldn't this just accept a ManifestGroup instead?
76
77
# Start with expected group level metadata
77
78
raise NotImplementedError
78
79
@@ -99,11 +100,11 @@ def get_zarr_metadata(manifest_group: ManifestGroup, key: str) -> Buffer:
99
100
# If requesting the root metadata, return the standard group metadata with additional dataset specific attributes
100
101
101
102
if key == "zarr.json" :
102
- metadata = manifest_group ._metadata .to_dict ()
103
+ metadata = manifest_group .metadata .to_dict ()
103
104
return dict_to_buffer (metadata , prototype = default_buffer_prototype ())
104
105
else :
105
106
var , _ = key .split ("/" )
106
- metadata = manifest_group ._manifest_arrays [var ].metadata .to_dict ()
107
+ metadata = manifest_group .arrays [var ].metadata .to_dict ()
107
108
return dict_to_buffer (metadata , prototype = default_buffer_prototype ())
108
109
109
110
@@ -170,16 +171,17 @@ def find_matching_store(stores: StoreDict, request_key: str) -> StoreRequest:
170
171
171
172
172
173
class ManifestStore (Store ):
173
- """A read-only Zarr store that uses obstore to access data on AWS, GCP, Azure. The requests
174
+ """
175
+ A read-only Zarr store that uses obstore to access data on AWS, GCP, Azure. The requests
174
176
from the Zarr API are redirected using the :class:`virtualizarr.manifests.ManifestGroup` containing
175
177
multiple :class:`virtualizarr.manifests.ManifestArray`,
176
178
allowing for virtually interfacing with underlying data in other file format.
177
179
178
-
179
180
Parameters
180
181
----------
181
- manifest_group : ManifestGroup
182
- Manifest Group containing Group metadata and mapping variable names to ManifestArrays
182
+ group : ManifestGroup
183
+ Root group of the store.
184
+ Contains group metadata, ManifestArrays, and any subgroups.
183
185
stores : dict[prefix, :class:`obstore.store.ObjectStore`]
184
186
A mapping of url prefixes to obstore Store instances set up with the proper credentials.
185
187
@@ -196,15 +198,15 @@ class ManifestStore(Store):
196
198
Modified from https://github.com/zarr-developers/zarr-python/pull/1661
197
199
"""
198
200
199
- _manifest_group : ManifestGroup
201
+ _group : ManifestGroup
200
202
_stores : StoreDict
201
203
202
204
def __eq__ (self , value : object ):
203
205
NotImplementedError
204
206
205
207
def __init__ (
206
208
self ,
207
- manifest_group : ManifestGroup ,
209
+ group : ManifestGroup ,
208
210
* ,
209
211
stores : StoreDict , # TODO: Consider using a sequence of tuples rather than a dict (see https://github.com/zarr-developers/VirtualiZarr/pull/490#discussion_r2010717898).
210
212
) -> None :
@@ -223,14 +225,17 @@ def __init__(
223
225
for store in stores .values ():
224
226
if not store .__class__ .__module__ .startswith ("obstore" ):
225
227
raise TypeError (f"expected ObjectStore class, got { store !r} " )
228
+
226
229
# TODO: Don't allow stores with prefix
227
- # TODO: Type check the manifest arrays
230
+ if not isinstance (group , ManifestGroup ):
231
+ raise TypeError
232
+
228
233
super ().__init__ (read_only = True )
229
234
self ._stores = stores
230
- self ._manifest_group = manifest_group
235
+ self ._group = group
231
236
232
237
def __str__ (self ) -> str :
233
- return f"ManifestStore({ self ._manifest_group } , { self ._stores } )"
238
+ return f"ManifestStore(group= { self ._group } , stores= { self ._stores } )"
234
239
235
240
def __getstate__ (self ) -> dict [Any , Any ]:
236
241
state = self .__dict__ .copy ()
@@ -257,10 +262,10 @@ async def get(
257
262
import obstore as obs
258
263
259
264
if key .endswith ("zarr.json" ):
260
- return get_zarr_metadata (self ._manifest_group , key )
265
+ return get_zarr_metadata (self ._group , key )
261
266
var , chunk_key = parse_manifest_index (key )
262
- marr = self ._manifest_group . _manifest_arrays [var ]
263
- manifest = marr ._manifest
267
+ marr = self ._group . arrays [var ]
268
+ manifest = marr .manifest
264
269
265
270
path = manifest ._paths [* chunk_key ]
266
271
offset = manifest ._offsets [* chunk_key ]
@@ -345,7 +350,7 @@ def list_prefix(self, prefix: str) -> AsyncGenerator[str, None]:
345
350
async def list_dir (self , prefix : str ) -> AsyncGenerator [str , None ]:
346
351
# docstring inherited
347
352
yield "zarr.json"
348
- for k in self ._manifest_group . _manifest_arrays .keys ():
353
+ for k in self ._group . arrays .keys ():
349
354
yield k
350
355
351
356
0 commit comments