Skip to content

Commit

Permalink
Use FsspecStore.from_url() for creation
Browse files Browse the repository at this point in the history
  • Loading branch information
will-moore committed Jan 22, 2025
1 parent 4d2d0ef commit b2d0f43
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 38 deletions.
40 changes: 18 additions & 22 deletions ome_zarr/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from collections.abc import Iterator
from typing import Any, Optional

from zarr.storage import FSStore
from zarr.storage import FsspecStore

LOGGER = logging.getLogger("ome_zarr.format")

Expand Down Expand Up @@ -60,7 +60,7 @@ def matches(self, metadata: dict) -> bool: # pragma: no cover
raise NotImplementedError()

@abstractmethod
def init_store(self, path: str, mode: str = "r") -> FSStore:
def init_store(self, path: str, mode: str = "r") -> FsspecStore:
raise NotImplementedError()

# @abstractmethod
Expand Down Expand Up @@ -134,9 +134,13 @@ def matches(self, metadata: dict) -> bool:
LOGGER.debug("%s matches %s?", self.version, version)
return version == self.version

def init_store(self, path: str, mode: str = "r") -> FSStore:
store = FSStore(path, mode=mode, dimension_separator=".")
LOGGER.debug("Created legacy flat FSStore(%s, %s)", path, mode)
def init_store(self, path: str, mode: str = "r") -> FsspecStore:
storage_options: dict[str, Any] = {}
# TODO: dimension_separator: "."
store = FsspecStore.from_url(
path, read_only=(mode == "r"), storage_options=storage_options
)
LOGGER.debug("Created legacy flat FsspecStore(%s, %s)", path, mode)
return store

def generate_well_dict(
Expand Down Expand Up @@ -180,30 +184,22 @@ class FormatV02(FormatV01):
def version(self) -> str:
return "0.2"

def init_store(self, path: str, mode: str = "r") -> FSStore:
def init_store(self, path: str, mode: str = "r") -> FsspecStore:
"""
Not ideal. Stores should remain hidden
TODO: could also check dimension_separator
"""

kwargs = {
"dimension_separator": "/",
"normalize_keys": False,
}

mkdir = True
print("format.init_store...", path, mode)
read_only = False
if "r" in mode or path.startswith(("http", "s3")):
# Could be simplified on the fsspec side
mkdir = False
if mkdir:
kwargs["auto_mkdir"] = True

store = FSStore(
path,
mode=mode,
**kwargs,
read_only = True

store = FsspecStore.from_url(
path, read_only=read_only
) # TODO: open issue for using Path
LOGGER.debug("Created nested FSStore(%s, %s, %s)", path, mode, kwargs)
LOGGER.debug("Created nested FsspecStore(%s, %s, %s)", path, mode)
print("...format.init_store: store:", store)
return store


Expand Down
16 changes: 9 additions & 7 deletions ome_zarr/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from urllib.parse import urljoin

import dask.array as da
from zarr.storage import FSStore
from zarr.storage import FsspecStore

from .format import CurrentFormat, Format, detect_format
from .types import JSONDict
Expand All @@ -20,7 +20,7 @@

class ZarrLocation:
"""
IO primitive for reading and writing Zarr data. Uses FSStore for all
IO primitive for reading and writing Zarr data. Uses FsspecStore for all
data access.
No assumptions about the existence of the given path string are made.
Expand All @@ -29,7 +29,7 @@ class ZarrLocation:

def __init__(
self,
path: Union[Path, str, FSStore],
path: Union[Path, str, FsspecStore],
mode: str = "r",
fmt: Format = CurrentFormat(),
) -> None:
Expand All @@ -40,16 +40,18 @@ def __init__(
self.__path = str(path.resolve())
elif isinstance(path, str):
self.__path = path
elif isinstance(path, FSStore):
elif isinstance(path, FsspecStore):
self.__path = path.path
else:
raise TypeError(f"not expecting: {type(path)}")

loader = fmt
if loader is None:
loader = CurrentFormat()
self.__store: FSStore = (
path if isinstance(path, FSStore) else loader.init_store(self.__path, mode)
self.__store: FsspecStore = (
path
if isinstance(path, FsspecStore)
else loader.init_store(self.__path, mode)
)

self.__init_metadata()
Expand Down Expand Up @@ -104,7 +106,7 @@ def path(self) -> str:
return self.__path

@property
def store(self) -> FSStore:
def store(self) -> FsspecStore:
"""Return the initialized store for this location"""
assert self.__store is not None
return self.__store
Expand Down
2 changes: 1 addition & 1 deletion ome_zarr/scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def __assert_values(self, pyramid: list[np.ndarray]) -> None:

def __create_group(
self, store: MutableMapping, base: np.ndarray, pyramid: list[np.ndarray]
) -> zarr.hierarchy.Group:
) -> zarr.Group:
"""Create group and datasets."""
grp = zarr.group(store)
grp.create_dataset("base", data=base)
Expand Down
16 changes: 8 additions & 8 deletions ome_zarr/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def write_multiscale(
:param pyramid:
The image data to save. Largest level first. All image arrays MUST be up to
5-dimensional with dimensions ordered (t, c, z, y, x)
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to store the data in
:type chunks: int or tuple of ints, optional
:param chunks:
Expand Down Expand Up @@ -305,7 +305,7 @@ def write_multiscales_metadata(
"""
Write the multiscales metadata in the group.
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type datasets: list of dicts
:param datasets:
Expand Down Expand Up @@ -385,7 +385,7 @@ def write_plate_metadata(
"""
Write the plate metadata in the group.
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type rows: list of str
:param rows: The list of names for the plate rows.
Expand Down Expand Up @@ -428,7 +428,7 @@ def write_well_metadata(
"""
Write the well metadata in the group.
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type images: list of dict
:param images: The list of dictionaries for all fields of views.
Expand Down Expand Up @@ -465,7 +465,7 @@ def write_image(
if the scaler argument is non-None.
Image array MUST be up to 5-dimensional with dimensions
ordered (t, c, z, y, x). Image can be a numpy or dask Array.
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type scaler: :class:`ome_zarr.scale.Scaler`
:param scaler:
Expand Down Expand Up @@ -664,7 +664,7 @@ def write_label_metadata(
The label data must have been written to a sub-group,
with the same name as the second argument.
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type name: str
:param name: The name of the label sub-group.
Expand Down Expand Up @@ -722,7 +722,7 @@ def write_multiscale_labels(
the image label data to save. Largest level first
All image arrays MUST be up to 5-dimensional with dimensions
ordered (t, c, z, y, x)
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type name: str, optional
:param name: The name of this labels data.
Expand Down Expand Up @@ -811,7 +811,7 @@ def write_labels(
if the scaler argument is non-None.
Label array MUST be up to 5-dimensional with dimensions
ordered (t, c, z, y, x)
:type group: :class:`zarr.hierarchy.Group`
:type group: :class:`zarr.Group`
:param group: The group within the zarr store to write the metadata in.
:type name: str, optional
:param name: The name of this labels data.
Expand Down

0 comments on commit b2d0f43

Please sign in to comment.