Description
Zarr version
v3.0.5
Numcodecs version
0.15.1
Python Version
3.13
Operating System
Mac
Installation
uv
Description
Hello! I'm trying to create an api around zarr async and I came across an edge case, maybe. I would like to be able to open the zarr store synchronously (potentially), but then use it asynchronously (hopefully). This seems to be specific to this store and not to zarr async i.e., the following works with a local file instead of an http server. Any advice? It would be great to write code that is synchronous at the top level, but then hooks into async at a lower level.
The weird part is that most of the anndata tests pass with this paradigm - the problem only arises in a script, or ipython sessions. This is likely just specific to remote stores, not some feature of how the program is run. Something to do with the event loop certainly? Any advice?
Steps to reproduce
ran in ipython/jupyter/script
from __future__ import annotations
import asyncio
import zarr.api
import zarr.api.asynchronous
async def main():
g = await zarr.api.asynchronous.open_array(
store="http://127.0.0.1:8080/242b59a3-7398-4f0d-89fc-73cbc886d1b9.zarr/X/data"
)
await g.getitem(Ellipsis) # works
g_sync = zarr.open_array(
"http://127.0.0.1:8080/242b59a3-7398-4f0d-89fc-73cbc886d1b9.zarr/X/data"
)
await (await zarr.api.asynchronous.open_array(store=g_sync.store)).getitem(
Ellipsis
) # fails
await g_sync._async_array.getitem(()) # fails
if __name__ == "__main__":
asyncio.run(main())
Traceback (most recent call last):
File "/Users/ilangold/Projects/Theis/anndata/tester.py", line 23, in <module>
asyncio.run(main())
~~~~~~~~~~~^^^^^^^^
File "/opt/homebrew/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/runners.py", line 194, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/opt/homebrew/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/opt/homebrew/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py", line 721, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/Users/ilangold/Projects/Theis/anndata/tester.py", line 17, in main
await (await zarr.api.asynchronous.open_array(store=g_sync.store)).getitem(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/zarr/api/asynchronous.py", line 1256, in open_array
return await AsyncArray.open(store_path, zarr_format=zarr_format)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/zarr/core/array.py", line 896, in open
metadata_dict = await get_array_metadata(store_path, zarr_format=zarr_format)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/zarr/core/array.py", line 177, in get_array_metadata
zarr_json_bytes, zarray_bytes, zattrs_bytes = await gather(
^^^^^^^^^^^^^
...<3 lines>...
)
^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/zarr/storage/_common.py", line 124, in get
return await self.store.get(self.path, prototype=prototype, byte_range=byte_range)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/zarr/storage/_fsspec.py", line 230, in get
value = prototype.buffer.from_bytes(await self.fs._cat_file(path))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/fsspec/implementations/http.py", line 234, in _cat_file
async with session.get(self.encode_url(url), **kw) as r:
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/aiohttp/client.py", line 1425, in __aenter__
self._resp: _RetType = await self._coro
^^^^^^^^^^^^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/aiohttp/client.py", line 607, in _request
with timer:
^^^^^
File "/Users/ilangold/Projects/Theis/anndata/venv/lib/python3.13/site-packages/aiohttp/helpers.py", line 636, in __enter__
raise RuntimeError("Timeout context manager should be used inside a task")
Additional output
No response