Skip to content

Commit 1202fb1

Browse files
committed
update ci; don't save temporary files for cachestore; add doctest env
1 parent 3d21514 commit 1202fb1

File tree

4 files changed

+44
-82
lines changed

4 files changed

+44
-82
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ jobs:
129129
pip install hatch
130130
- name: Set Up Hatch Env
131131
run: |
132-
hatch env create docs
133-
hatch env run -e docs list-env
132+
hatch env create doctest
133+
hatch env run doctest:list-env
134134
- name: Run Tests
135135
run: |
136-
hatch env run --env docs check
136+
hatch env run doctest:test
137137
138138
test-complete:
139139
name: Test complete

docs/user-guide/experimental.md

Lines changed: 18 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ can be any Store implementation, providing flexibility in cache persistence:
2626

2727
```python exec="true" session="experimental" source="above" result="ansi"
2828
import zarr
29-
import zarr.storage
29+
from zarr.storage import LocalStore
3030
import numpy as np
31+
from tempfile import mkdtemp
3132
from zarr.experimental.cache_store import CacheStore
3233

3334
# Create a local store and a separate cache store
34-
source_store = zarr.storage.LocalStore('test.zarr')
35+
local_store_path = mkdtemp(suffix='.zarr')
36+
source_store = LocalStore(local_store_path)
3537
cache_store = zarr.storage.MemoryStore() # In-memory cache
3638
cached_store = CacheStore(
3739
store=source_store,
@@ -63,7 +65,7 @@ for _ in range(100):
6365
elapsed_cache = time.time() - start
6466

6567
# Compare with direct store access (without cache)
66-
zarr_array_nocache = zarr.open('test.zarr', mode='r')
68+
zarr_array_nocache = zarr.open(local_store_path, mode='r')
6769
start = time.time()
6870
for _ in range(100):
6971
_ = zarr_array_nocache[:]
@@ -75,45 +77,6 @@ speedup = elapsed_nocache / elapsed_cache
7577

7678
Cache effectiveness is particularly pronounced with repeated access to the same data chunks.
7779

78-
## Remote Store Caching
79-
80-
The CacheStore is most beneficial when used with remote stores where network latency
81-
is a significant factor. You can use different store types for source and cache:
82-
83-
```python
84-
# This example shows remote store setup but requires network access
85-
# from zarr.storage import FsspecStore, LocalStore
86-
87-
# # Create a remote store (S3 example) - for demonstration only
88-
# remote_store = FsspecStore.from_url('s3://bucket/data.zarr', storage_options={'anon': True})
89-
90-
# # Use a local store for persistent caching
91-
# local_cache_store = LocalStore('cache_data')
92-
93-
# # Create cached store with persistent local cache
94-
# cached_store = CacheStore(
95-
# store=remote_store,
96-
# cache_store=local_cache_store,
97-
# max_size=512*1024*1024 # 512MB cache
98-
# )
99-
100-
# # Open array through cached store
101-
# z = zarr.open(cached_store)
102-
103-
# For demonstration, use local stores instead
104-
from zarr.storage import LocalStore
105-
local_source = LocalStore('remote_data.zarr')
106-
local_cache = LocalStore('cache_data')
107-
cached_store = CacheStore(
108-
store=local_source,
109-
cache_store=local_cache,
110-
max_size=512*1024*1024 # 512MB cache
111-
)
112-
```
113-
114-
The first access to any chunk will be slow (network retrieval), but subsequent accesses
115-
to the same chunk will be served from the local cache, providing dramatic speedup.
116-
The cache persists between sessions when using a LocalStore for the cache backend.
11780

11881
## Cache Configuration
11982

@@ -232,7 +195,10 @@ and use any store type for the cache backend:
232195
```python exec="true" session="experimental-memory-cache" source="above" result="ansi"
233196
from zarr.storage import LocalStore, MemoryStore
234197
from zarr.experimental.cache_store import CacheStore
235-
source_store = LocalStore('data.zarr')
198+
from tempfile import mkdtemp
199+
200+
local_store_path = mkdtemp(suffix='.zarr')
201+
source_store = LocalStore(local_store_path)
236202
cache_store = MemoryStore()
237203
cached_store = CacheStore(
238204
store=source_store,
@@ -241,40 +207,16 @@ cached_store = CacheStore(
241207
)
242208
```
243209

244-
### Remote Store with Local Cache
245-
246-
```python exec="true" session="experimental-remote-cache" source="above" result="ansi"
247-
# Remote store example (commented out as it requires network access)
248-
# from zarr.storage import FsspecStore, LocalStore
249-
# remote_store = FsspecStore.from_url('s3://bucket/data.zarr', storage_options={'anon': True})
250-
# local_cache = LocalStore('local_cache')
251-
# cached_store = CacheStore(
252-
# store=remote_store,
253-
# cache_store=local_cache,
254-
# max_size=1024*1024*1024,
255-
# max_age_seconds=3600
256-
# )
257-
258-
# Local store example for demonstration
259-
from zarr.storage import LocalStore
260-
from zarr.experimental.cache_store import CacheStore
261-
remote_like_store = LocalStore('remote_like_data.zarr')
262-
local_cache = LocalStore('local_cache')
263-
cached_store = CacheStore(
264-
store=remote_like_store,
265-
cache_store=local_cache,
266-
max_size=1024*1024*1024,
267-
max_age_seconds=3600
268-
)
269-
```
270-
271210
### Memory Store with Persistent Cache
272211

273212
```python exec="true" session="experimental-local-cache" source="above" result="ansi"
213+
from tempfile import mkdtemp
274214
from zarr.storage import MemoryStore, LocalStore
275215
from zarr.experimental.cache_store import CacheStore
216+
276217
memory_store = MemoryStore()
277-
persistent_cache = LocalStore('persistent_cache')
218+
local_store_path = mkdtemp(suffix='.zarr')
219+
persistent_cache = LocalStore(local_store_path)
278220
cached_store = CacheStore(
279221
store=memory_store,
280222
cache_store=persistent_cache,
@@ -290,14 +232,16 @@ of source and cache stores for your specific use case.
290232
Here's a complete example demonstrating cache effectiveness:
291233

292234
```python exec="true" session="experimental-final" source="above" result="ansi"
235+
import numpy as np
236+
import time
237+
from tempfile import mkdtemp
293238
import zarr
294239
import zarr.storage
295-
import time
296-
import numpy as np
297240
from zarr.experimental.cache_store import CacheStore
298241

299242
# Create test data with dual-store cache
300-
source_store = zarr.storage.LocalStore('benchmark.zarr')
243+
local_store_path = mkdtemp(suffix='.zarr')
244+
source_store = zarr.storage.LocalStore(local_store_path)
301245
cache_store = zarr.storage.MemoryStore()
302246
cached_store = CacheStore(
303247
store=source_store,

docs/user-guide/storage.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ group = zarr.create_group(store='data/foo/bar')
2323
print(group)
2424
```
2525

26-
```python exec="true" session="storage" source="above" result="ansi"
26+
```python
2727
# Implicitly create a read-only FsspecStore
28+
# Note: requires s3fs to be installed
2829
group = zarr.open_group(
2930
store='s3://noaa-nwm-retro-v2-zarr-pds',
3031
mode='r',
@@ -58,7 +59,8 @@ print(group)
5859
```
5960

6061
- an FSSpec URI string, indicating a [remote store](#remote-store) location:
61-
```python exec="true" session="storage" source="above" result="ansi"
62+
```python
63+
# Note: requires s3fs to be installed
6264
group = zarr.open_group(
6365
store='s3://noaa-nwm-retro-v2-zarr-pds',
6466
mode='r',
@@ -124,7 +126,8 @@ such as cloud object storage (e.g. AWS S3, Google Cloud Storage, Azure Blob Stor
124126
that implements the [AbstractFileSystem](https://filesystem-spec.readthedocs.io/en/stable/api.html#fsspec.spec.AbstractFileSystem)
125127
API. `storage_options` can be used to configure the fsspec backend:
126128

127-
```python exec="true" session="storage" source="above" result="ansi"
129+
```python
130+
# Note: requires s3fs to be installed
128131
store = zarr.storage.FsspecStore.from_url(
129132
's3://noaa-nwm-retro-v2-zarr-pds',
130133
read_only=True,
@@ -137,7 +140,8 @@ print(group)
137140
The type of filesystem (e.g. S3, https, etc..) is inferred from the scheme of the url (e.g. s3 for "**s3**://noaa-nwm-retro-v2-zarr-pds").
138141
In case a specific filesystem is needed, one can explicitly create it. For example to create a S3 filesystem:
139142

140-
```python exec="true" session="storage" source="above" result="ansi"
143+
```python
144+
# Note: requires s3fs to be installed
141145
import fsspec
142146
fs = fsspec.filesystem(
143147
's3', anon=True, asynchronous=True,

pyproject.toml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,19 @@ check = "mkdocs build --strict"
257257
readthedocs = "rm -rf $READTHEDOCS_OUTPUT/html && cp -r site $READTHEDOCS_OUTPUT/html"
258258
list-env = "pip list"
259259

260+
[tool.hatch.envs.doctest]
261+
description = "Test environment for validating executable code blocks in documentation"
262+
features = ['test', 'remote'] # Include remote dependencies for s3fs
263+
dependencies = [
264+
"pytest",
265+
"pytest-examples",
266+
]
267+
268+
[tool.hatch.envs.doctest.scripts]
269+
test = "pytest tests/test_docs.py -v"
270+
test-file = "python tests/test_docs.py --test {args}"
271+
list-env = "pip list"
272+
260273
[tool.ruff]
261274
line-length = 100
262275
force-exclude = true
@@ -396,7 +409,8 @@ addopts = [
396409
]
397410
filterwarnings = [
398411
"error",
399-
"ignore:Unclosed client session <aiohttp.client.ClientSession.*:ResourceWarning"
412+
"ignore:Unclosed client session <aiohttp.client.ClientSession.*:ResourceWarning",
413+
"ignore:Numcodecs codecs are not in the Zarr version 3 specification.*:UserWarning"
400414
]
401415
markers = [
402416
"asyncio: mark test as asyncio test",

0 commit comments

Comments
 (0)