nodes
Every object abczarr hands back, an array or a group, is a node. ZarrNode is the common base: it carries the store path, the Zarr format version, the metadata, and the user attributes, and it is where the capability query lives.
ZarrArray is the n-dimensional node. Read and write it like a NumPy array, with NumPy-style selections:
ZarrGroup is the container node. It
holds other nodes by name, arrays and groups alike, and behaves like a
mapping: group["images"], group.keys(), "images" in group.
Every node has a coroutine twin. Open one with asynchronous=True -- which
returns a coroutine you await, opening asynchronously -- or convert a node
you already hold with as_async; go back
with as_sync. The async array
reads and writes through methods, not [] -- an assignment expression
cannot be awaited:
array = await abczarr.open("data.zarr", mode="a", asynchronous=True)
block = await array.getitem((slice(0, 64), slice(0, 64)))
await array.setitem((slice(0, 64), slice(0, 64)), block * 2)
A backend that is natively async (tensorstore, zarr-python) awaits its own
futures; one that is not runs its blocking ops in a bounded thread pool.
array.supports("async", native=True) says which you got.
abczarr.abc.sync
The synchronous Zarr node classes: the shared base, the array, and the group.
ZarrNode is the base class both ZarrArray and ZarrGroup inherit from. It defines the metadata, the user attributes, the Zarr format version, and the capability query that every node shares.
- ZarrArray is the n-dimensional node. It is read and written like a NumPy array.
- ZarrGroup is the container node. It is indexed like a mapping, with subgroups and arrays as its members. PathGroup implements a group for a backend that has no group object of its own.
Attributes
KNOWN_CAPABILITIES
module-attribute
KNOWN_CAPABILITIES = frozenset({'sharding', 'async', 'consolidated_metadata', 'codecs_v2', 'codecs_v3', 'listing', 'writes', 'deletes', 'partial_read', 'partial_write', 'transactions', 'atomic_transactions'})
Classes
Support
Bases: Enum
How well a driver provides a capability.
NATIVE means the backend performs the operation directly, the
fast path. SYNTHESIZED means abczarr builds the operation from
simpler ones. The result is correct, but possibly slower than a
backend that performs the operation directly. NONE means the
operation is not available at all, and raises
UnsupportedZarrOperation.
bool(support) is True unless the value is NONE. A plain
truth test therefore answers whether the operation can happen at
all, regardless of how.
Example
Attributes
Methods:
ZarrNode
Bases: SupportsCapabilities, ABC
The base class for a Zarr array or a Zarr group.
A ZarrNode carries what every Zarr object shares: its location,
its metadata, its user attributes, its OME-Zarr metadata, and its
format version.
ZarrArray and
ZarrGroup add the data-specific
surface on top of it.
A node's backend determines which capabilities it has. Use [capability][abczarr.abc.capabilities.SupportsCapabilities.capability] to find out how a given capability is provided, and [supports][abczarr.abc.capabilities.SupportsCapabilities.supports] to check whether it is provided at all.
Attributes
native
property
native: Any
The underlying backend object, or None when the node
has none.
This property is the escape hatch for anything the uniform
node surface does not expose. A zarr.Array, a
tensorstore.TensorStore, or another backend's own object is
reachable here, with its full native API. A node backed by
nothing but a path, such as a
PathGroup, has no such object
and returns None.
attrs
property
This node's user attributes, as a live, write-through mapping.
Reads come from this node's metadata, which is the single
source of truth for what the mapping holds. A write persists
immediately: node.attrs["unit"] = "micrometer" adds or
replaces the key, and del node.attrs["unit"] removes it.
Both operations are written through the node's own
persistence path, so the change reaches the store before the
call returns.
ome
deletable
property
writable
ome: OME | None
This node's OME-Zarr metadata as a typed object, read and write.
Reading parses the node's OME-NGFF metadata and returns the
matching version's OME object, or
None when the node carries no OME metadata. Assigning a
value serializes and persists it, write-through in the same
way as attrs. The assigned
value may be a typed OME object or a
plain JSON-style mapping that carries a version key.
Deleting the attribute, with del node.ome, removes the
metadata.
Both directions understand every NGFF envelope. From version
0.5 on, the metadata is nested under a single "ome"
attribute. Before 0.5, its fields are written directly at the
top level of the node's attributes. Neither direction touches
any attribute that is not part of the OME metadata.
zarr_version
abstractmethod
property
The Zarr format version this node was written with.
Methods:
update_ome
Merge OME metadata into this node's existing OME metadata, and persist the result.
This method is the OME-metadata counterpart of
update_attributes.
A top-level key present in ome, such as version,
multiscales or omero, replaces the value already
stored under that key. A key the node already carries that
ome does not name is preserved. When the node has no OME
metadata yet and the merged result still names no version,
the metadata is written with the latest released OME version.
The merge is shallow. A nested structure, such as a multiscale or a plate definition, is replaced as a whole rather than merged recursively. For a structured edit, read ome, change the typed object, and assign the result back.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ome
|
OME or dict
|
The metadata whose top-level keys are merged in. |
required |
Returns:
| Type | Description |
|---|---|
ZarrNode
|
This node, with the merged metadata visible on ome. |
update_attributes
Add or replace several attributes at once, and persist the change.
The keys in attributes are merged into this node's existing
attributes. An existing key is overwritten with the new
value, and every other key is kept unchanged. The merged
result is written through the node's persistence path before
this method returns. The behavior mirrors zarr-python's own
update_attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes
|
dict
|
The attributes to add or replace. Values must be JSON-compatible. |
required |
Returns:
| Type | Description |
|---|---|
ZarrNode
|
ZarrArray
Bases: ZarrNode
An n-dimensional Zarr array.
A ZarrArray is read and written like a NumPy array. Indexing
accepts NumPy-style selections, including integers, slices, and
ellipses.
Attributes
chunks
abstractmethod
property
chunks: Shape
The chunk shape of the array.
This property raises when the array's chunk grid is not regular.
shards
abstractmethod
property
shards: Shape | None
The shard shape of the array, or None if it is not
sharded.
This property raises when the array's shard grid is not regular.
Methods:
__getitem__
abstractmethod
Read data from the array at index (a NumPy-style
selection).
__setitem__
abstractmethod
Write value at index (a NumPy-style selection).
__array__
Convert this array to a NumPy array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dtype
|
dtype
|
The dtype of the returned array. |
None
|
copy
|
bool
|
Whether to copy the data. NumPy 2's array protocol passes
this argument. Reading the array always materializes a
fresh array in memory, so a view without copying is never
possible. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
as_async
as_async() -> AsyncZarrArray
The coroutine twin of this array, over the same backend handle.
By default, the returned twin runs this array's reads and
writes in a bounded thread pool, and its "async" capability
reports Support.SYNTHESIZED. A driver whose backend has its
own coroutine surface returns a Support.NATIVE twin instead,
one that awaits the backend's own futures directly rather than
running in a thread.
to_dask
to_dask(chunks: str | ShapeLike | None = None) -> Array
Convert this array to a Dask array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chunks
|
optional
|
The Dask block size. Three spellings are accepted.
|
None
|
store
Write source into this array, block by block.
source is any array-like object whose shape matches this
array's. A Dask array is written one block at a time, so a
source too large to fit in memory is never fully
materialized. A plain array is written in a single write.
This method is the write counterpart of
to_dask. It works for
every backend, unlike dask.array.to_zarr, which requires a
native zarr.Array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
array - like
|
The data to write. Its shape must match this array's. |
required |
lock
|
bool or str
|
Whether to serialize concurrent block writes. The
default, |
'auto'
|
ZarrGroup
Bases: ZarrNode
A Zarr group: a container of arrays and subgroups.
A ZarrGroup is indexed like a mapping. Each member, whether an
array or a subgroup, is reached by its name.
Methods:
__setitem__
abstractmethod
Set the subgroup or array named key.
create_group
abstractmethod
Create a subgroup named name, or open it if one already
exists.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The subgroup's name. |
required |
overwrite
|
bool
|
Replace an existing member named |
False
|
Returns:
| Type | Description |
|---|---|
ZarrGroup
|
The created or opened subgroup. |
create_array
create_array(name: str, shape: ShapeLike | None = None, dtype: DTypeLike | None = None, *, data: ArrayLike | None = None, config: ArrayConfig | ArrayOptions | None = None, **options: Unpack[ArrayOptions]) -> ZarrArray
Create a new array named name within this group.
The array is created from existing data when data is given. The
array's shape and dtype then default to the data's, and the data is
written into the new array. A shape or dtype passed explicitly, or
one carried by config, takes precedence over the data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The array's name. |
required |
shape
|
tuple of int
|
The array's shape. Required unless |
None
|
dtype
|
numpy dtype
|
The array's data type. Required unless |
None
|
data
|
array - like
|
Existing data to size the array from and write into it. |
None
|
config
|
ArrayConfig or mapping
|
A reusable ArrayConfig, or a mapping of the same fields. Individual fields may also be passed as keyword arguments, which override the config. |
None
|
**options
|
Unpack[ArrayOptions]
|
Individual ArrayConfig fields,
such as |
{}
|
Returns:
| Type | Description |
|---|---|
ZarrArray
|
The newly created array. |
as_async
as_async() -> AsyncZarrGroup
The coroutine twin of this group, over the same backend handle.
By default, the returned twin runs this group's navigation
and creation in a bounded thread pool, and its "async"
capability reports Support.SYNTHESIZED. A group that stores
its members as directories, such as a
PathGroup, and a backend with
its own async group both return a Support.NATIVE twin
instead.
PathGroup
PathGroup(store_path: PathLike, mode: str = 'r')
Bases: ZarrGroup
A group backed by nothing but a key-value store.
Some backends do not provide a group object of their own.
TensorStore opens only arrays, and a plain key-value store holds
only keys. A PathGroup supplies the full group surface over such
a backend. In that setting, a group is a location that carries
Zarr group metadata. The PathGroup reads that metadata, lists
the group's members, and navigates into its subgroups and arrays.
It can also create a subgroup, which requires only writing new
group metadata.
A backend adapts a PathGroup by subclassing it and overriding
_open_array to open a child array through the backend. A
subclass that also creates arrays overrides _create_array. A
subgroup needs no override, because a subgroup is another
PathGroup of the same subclass. An entire hierarchy is therefore
reachable from a single opened group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store_path
|
PathLike
|
The group's directory in its store. |
required |
mode
|
str
|
The access mode child arrays are opened with ( |
'r'
|
Attributes
Methods:
keys
The names of this group's members, in store order.
A member may be a subgroup or an array. Both kinds are included.
create_group
Create a subgroup named name, or open it if one already
exists.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The subgroup's name. |
required |
overwrite
|
bool
|
Replace an existing member named |
False
|
Returns:
| Type | Description |
|---|---|
PathGroup
|
The created or opened subgroup. |
as_async
as_async() -> AsyncPathGroup
The coroutine twin of this group: a native async path group.
The returned
AsyncPathGroup
lists and navigates its members directly through an
AsyncStore over the group's
location, rather than running the synchronous listing in a
thread. Its array children are opened in the async color as
well. Its "async" capability reports Support.NATIVE.
abczarr.abc.asynchronous
The asynchronous Zarr node classes: the coroutine twins of the synchronous surface.
AsyncZarrNode is the coroutine twin of ZarrNode, the base class both the async array and the async group inherit from. Its data I/O is coroutines. Its metadata, attributes, format version, and capability query stay synchronous, because none of them touch the node's data path.
Every async node has a synchronous twin over the same backend handle, reached with as_sync. A synchronous node's own as_async returns the async twin in the other direction. The non-blocking accessors delegate to the synchronous twin, so the two colors always report the same metadata, attributes and backend features.
AsyncZarrArray reads and
writes through methods rather than indexing: await
array.getitem(index) and await array.setitem(index, value).
AsyncZarrGroup reaches a
member with await group.getitem(name), iterates member names with
async for, and creates children with await. It has two concrete
implementations: the native
AsyncPathGroup, and the
thread-pool fallback
ThreadedAsyncGroup.
Classes
AsyncZarrNode
Bases: SupportsCapabilities, ABC
The coroutine twin of a ZarrNode.
Only data I/O differs from the synchronous node: it is coroutines here. The non-blocking accessors, including metadata, attributes, format version, location, and the capability query, delegate to the synchronous twin, so both colors always agree. Use [capability][abczarr.abc.capabilities.SupportsCapabilities.capability] or [supports][abczarr.abc.capabilities.SupportsCapabilities.supports] to check whether the async surface is native to the backend or synthesized in a thread pool.
Attributes
native
property
native: Any
The underlying backend object, or None when the node has
none.
This property is the escape hatch for anything the uniform node surface does not expose.
attrs
property
This node's user attributes, as a read-only, cached mapping.
Reading this mapping is synchronous. The values come from the node's cached metadata, so no I/O is needed and there is nothing to await. Assigning a single key cannot be awaited, so this mapping has no per-key async setter. Persisting a change requires update_attributes, which writes the whole set of attributes through the node's async persistence path.
ome
property
ome: OME | None
This node's OME-Zarr metadata as a typed object, read only.
Reading this property is synchronous, like
attrs. The
metadata is parsed from the node's cached attributes, so no
I/O is needed. The property returns the matching version's
OME object, or None when the node
carries no OME metadata. Writing cannot be awaited through a
plain assignment, so this property has no setter. Use
set_ome,
update_ome,
or del_ome
to persist a change, the same reason the async node writes
attributes through update_attributes rather than through
item assignment.
Methods:
set_ome
async
set_ome(value: OME | JsonDict) -> AsyncZarrNode
Store OME metadata on this node, and persist it.
This method is the coroutine twin of assigning
ZarrNode.ome. It serializes
value into the envelope its version calls for: the
"ome" attribute from version 0.5 on, or the bare
top-level attribute keys before 0.5. The serialized metadata
is then written through the node's async persistence path.
Any OME metadata already present is replaced, and every other
attribute is left untouched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
OME or dict
|
The metadata to store, typed or a plain mapping carrying a
|
required |
Returns:
| Type | Description |
|---|---|
AsyncZarrNode
|
This node, with the metadata visible on ome. |
update_ome
async
update_ome(ome: OME | JsonDict) -> AsyncZarrNode
Merge OME metadata into this node's existing OME metadata, and persist the result.
This method is the coroutine twin of
ZarrNode.update_ome.
A top-level key present in ome replaces the value already
stored under that key on the node's current OME metadata. A
key the node already carries that ome does not name is
kept. When the node has no OME metadata yet and the merged
result still names no version, the metadata is written with
the latest released OME version.
The merge is shallow. A nested structure, such as a multiscale or a plate definition, is replaced as a whole rather than merged recursively. For a structured edit, read ome, change the typed object, and pass the result to set_ome.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ome
|
OME or dict
|
The metadata whose top-level keys are merged in. |
required |
Returns:
| Type | Description |
|---|---|
AsyncZarrNode
|
This node, with the merged metadata visible on ome. |
del_ome
async
del_ome() -> AsyncZarrNode
Remove this node's OME-Zarr metadata, and persist the removal.
This method is the coroutine twin of del node.ome on
ZarrNode.ome. It drops the
OME attribute keys of whichever envelope the node uses. Every
other attribute is left untouched. A node that carries no OME
metadata is left unchanged.
Returns:
| Type | Description |
|---|---|
AsyncZarrNode
|
This node. |
update_attributes
async
update_attributes(attributes: JsonDict) -> AsyncZarrNode
Add or replace several attributes at once, and persist the change.
This method is the coroutine twin of
ZarrNode.update_attributes.
The keys in attributes are merged into this node's existing
attributes. The merged result is written through the node's
async persistence path. The behavior mirrors zarr-python's
own async update_attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes
|
dict
|
The attributes to add or replace. Values must be JSON-compatible. |
required |
Returns:
| Type | Description |
|---|---|
AsyncZarrNode
|
This node, with the updated attributes visible on |
capability
How this async node provides the capability name.
For "async", the answer is this twin's own: native or
synthesized, depending on the backend. For every other name,
the answer comes from the synchronous twin, so the two colors
always report the same backend features.
AsyncZarrArray
AsyncZarrArray(sync: ZarrArray)
Bases: AsyncZarrNode
The coroutine twin of a ZarrArray.
An AsyncZarrArray is read and written with await, through the
getitem and setitem methods rather than indexing.
Example
Attributes
Methods:
getitem
abstractmethod
async
Read data from the array at index (a NumPy-style selection).
ThreadedAsyncArray
ThreadedAsyncArray(sync: ZarrArray)
Bases: AsyncZarrArray
An AsyncZarrArray that runs a synchronous array's reads and writes in a bounded thread pool.
This class is the default async array for a backend that has no
coroutine surface of its own. It reports "async" as
Support.SYNTHESIZED.
AsyncZarrGroup
AsyncZarrGroup(sync: ZarrGroup)
Bases: AsyncZarrNode
The coroutine twin of a ZarrGroup.
An AsyncZarrGroup reaches a member with await
group.getitem(name), iterates member names with async for,
and creates a subgroup or an array with await.
Example
Methods:
getitem
abstractmethod
async
getitem(key: str) -> AsyncZarrNode
Open the subgroup or array named key as an async node.
create_array
async
create_array(name: str, shape: ShapeLike | None = None, dtype: DTypeLike | None = None, *, data: ArrayLike | None = None, config: ArrayConfig | ArrayOptions | None = None, **options: Unpack[ArrayOptions]) -> AsyncZarrArray
Create a new array named name within this group.
This method mirrors
ZarrGroup.create_array.
When data is given, the data is written into the new array
through the backend's native asynchronous write.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The array's name. |
required |
shape
|
tuple of int
|
The array's shape. Required unless |
None
|
dtype
|
numpy dtype
|
The array's data type. Required unless |
None
|
data
|
array - like
|
Existing data to size the array from and write into it. |
None
|
config
|
ArrayConfig or mapping
|
A reusable ArrayConfig, or a mapping of the same fields. Individual fields may also be passed as keyword arguments, which override the config. |
None
|
**options
|
Unpack[ArrayOptions]
|
Individual ArrayConfig
fields, such as |
{}
|
Returns:
| Type | Description |
|---|---|
AsyncZarrArray
|
The newly created array. |
create_group
abstractmethod
async
create_group(name: str, overwrite: bool = False) -> AsyncZarrGroup
Create or open a subgroup named name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The subgroup's name. |
required |
overwrite
|
bool
|
Replace an existing member named |
False
|
Returns:
| Type | Description |
|---|---|
AsyncZarrGroup
|
The created or opened subgroup. |
AsyncPathGroup
AsyncPathGroup(sync: PathGroup)
Bases: AsyncZarrGroup
The async twin of PathGroup.
Listing and navigating members is genuinely non-blocking, carried out through an async store rather than a synchronous group run in a thread. Array children come back in the async color. When the underlying backend is itself natively async, a child array is that backend's own native async array, not a synchronous array bridged through a thread. Creating a subgroup or an array still blocks, because writing metadata and building a backend handle are inherently synchronous operations.
This group's own "async" capability always reports
Support.SYNTHESIZED, even when the underlying store is itself
natively async. Support.NATIVE is reserved for async support
that a backend provides directly.
Methods:
getitem
async
getitem(key: str) -> AsyncZarrNode
Open the subgroup or array named key as an async node.
create_group
async
create_group(name: str, overwrite: bool = False) -> AsyncPathGroup
Create or open a subgroup named name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The subgroup's name. |
required |
overwrite
|
bool
|
Replace an existing member named |
False
|
Returns:
| Type | Description |
|---|---|
AsyncPathGroup
|
The created or opened subgroup. |
ThreadedAsyncGroup
ThreadedAsyncGroup(sync: ZarrGroup)
Bases: AsyncZarrGroup
An AsyncZarrGroup that runs a synchronous group's navigation and creation in a bounded thread pool.
This class is the fallback for a group that is neither natively async nor path-based. A path-based backend gets the native AsyncPathGroup instead. Members this group opens are handed back in the async color.
Methods:
getitem
async
getitem(key: str) -> AsyncZarrNode
Open the subgroup or array named key as an async node.
create_group
async
create_group(name: str, overwrite: bool = False) -> AsyncZarrGroup
Create or open a subgroup named name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The subgroup's name. |
required |
overwrite
|
bool
|
Replace an existing member named |
False
|
Returns:
| Type | Description |
|---|---|
AsyncZarrGroup
|
The created or opened subgroup. |