|
6 | 6 |
|
7 | 7 | The `GroupSpec` and `ArraySpec` classes represent Zarr v2 groups and arrays, respectively. To create an instance of a `GroupSpec` or `ArraySpec` from an existing Zarr group or array, pass the Zarr group / array to the `.from_zarr` method defined on the `GroupSpec` / `ArraySpec` classes. This will result in a `pydantic-zarr` model of the Zarr object. |
8 | 8 |
|
9 | | -Note that `GroupSpec.from_zarr(zarr_group)` will traverse the entire hierarchy under `zarr_group`. Future versions of this library may introduce a limit on the depth of this traversal: see [#2](https://github.com/d-v-b/pydantic-zarr/issues/2). |
| 9 | +> By default `GroupSpec.from_zarr(zarr_group)` will traverse the entire hierarchy under `zarr_group`. This can be extremely slow if used on an extensive Zarr group on high latency storage. To limit the depth of traversal to a specific depth, use the `depth` keyword argument, e.g. `GroupSpec.from_zarr(zarr_group, depth=1)` |
10 | 10 |
|
11 | 11 | Note that `from_zarr` will *not* read the data inside an array. |
12 | 12 |
|
@@ -78,7 +78,7 @@ print(dict(group2['bar'].attrs)) |
78 | 78 |
|
79 | 79 | ### Creating from an array |
80 | 80 |
|
81 | | -The `ArraySpec` class has a `from_array` static method that takes a numpy-array-like object and returns an `ArraySpec` with `shape` and `dtype` fields matching those of the array-like object. |
| 81 | +The `ArraySpec` class has a `from_array` static method that takes an array-like object and returns an `ArraySpec` with `shape` and `dtype` fields matching those of the array-like object. |
82 | 82 |
|
83 | 83 | ```python |
84 | 84 | from pydantic_zarr.v2 import ArraySpec |
@@ -241,53 +241,64 @@ print(GroupSpec.from_flat(tree).model_dump()) |
241 | 241 |
|
242 | 242 | The `like` method works by converting both input models to `dict` via `pydantic.BaseModel.model_dump`, and comparing the `dict` representation of the models. This means that instances of two different subclasses of `GroupSpec`, which would not be considered equal according to the `==` operator, will be considered `like` if and only if they serialize to identical `dict` instances. |
243 | 243 |
|
244 | | -The `like` method also takes keyword arguments `include` and `exclude`, which results in attributes being explicitly included or excluded from the model comparison. So it's possible to use `like` to check if two `ArraySpec` instances have the same `shape` and `dtype` by calling `array_a.like(array_b, include={'shape', 'dtype'})`. This is useful if you don't care about the compressor or filters and just want to ensure that you can safely write an in-memory array to a Zarr array. |
| 244 | +The `like` method takes keyword arguments `include` and `exclude`, which determine the attributes included or excluded from the model comparison. So it's possible to use `like` to check if two `ArraySpec` instances have the same `shape`, `dtype` and `chunks` by calling `array_a.like(array_b, include={'shape', 'dtype', 'chunks'})`. This is useful if you don't care about the compressor or filters and just want to ensure that you can safely write an in-memory array to a Zarr array, which depends just on the two arrays having matching `shape`, `dtype`, and `chunks` attributes. |
245 | 245 |
|
246 | 246 | ```python |
247 | 247 | from pydantic_zarr.v2 import ArraySpec, GroupSpec |
248 | 248 | import zarr |
249 | 249 | arr_a = ArraySpec(shape=(1,), dtype='uint8', chunks=(1,)) |
250 | | -arr_b = ArraySpec(shape=(2,), dtype='uint8', chunks=(1,)) # array with different shape |
| 250 | +# make an array with a different shape |
| 251 | +arr_b = ArraySpec(shape=(2,), dtype='uint8', chunks=(1,)) |
251 | 252 |
|
252 | | -print(arr_a.like(arr_b)) # False, because of mismatched shape |
| 253 | +# Returns False, because of mismatched shape |
| 254 | +print(arr_a.like(arr_b)) |
253 | 255 | #> False |
254 | 256 |
|
255 | | -print(arr_a.like(arr_b, exclude={'shape'})) # True, because we exclude shape. |
| 257 | +# Returns True, because we exclude shape. |
| 258 | +print(arr_a.like(arr_b, exclude={'shape'})) |
256 | 259 | #> True |
257 | 260 |
|
258 | 261 | # `ArraySpec.like` will convert a zarr.Array to ArraySpec |
259 | 262 | store = zarr.MemoryStore() |
260 | | -arr_a_stored = arr_a.to_zarr(store, path='arr_a') # this is a zarr.Array |
| 263 | +# This is a zarr.Array |
| 264 | +arr_a_stored = arr_a.to_zarr(store, path='arr_a') |
261 | 265 |
|
262 | | -print(arr_a.like(arr_a_stored)) # arr_a is like the zarr.Array version of itself |
| 266 | +# arr_a is like the zarr.Array version of itself |
| 267 | +print(arr_a.like(arr_a_stored)) |
263 | 268 | #> True |
264 | 269 |
|
265 | | -print(arr_b.like(arr_a_stored)) # False, because of mismatched shape |
| 270 | +# Returns False, because of mismatched shape |
| 271 | +print(arr_b.like(arr_a_stored)) |
266 | 272 | #> False |
267 | 273 |
|
268 | | -print(arr_b.like(arr_a_stored, exclude={'shape'})) # True, because we exclude shape. |
| 274 | +# Returns True, because we exclude shape. |
| 275 | +print(arr_b.like(arr_a_stored, exclude={'shape'})) |
269 | 276 | #> True |
270 | 277 |
|
271 | | -# the same thing thing for groups |
| 278 | +# The same thing, but for groups |
272 | 279 | g_a = GroupSpec(attributes={'foo': 10}, members={'a': arr_a, 'b': arr_b}) |
273 | 280 | g_b = GroupSpec(attributes={'foo': 11}, members={'a': arr_a, 'b': arr_b}) |
274 | 281 |
|
275 | | -print(g_a.like(g_a)) # g_a is like itself |
| 282 | +# g_a is like itself |
| 283 | +print(g_a.like(g_a)) |
276 | 284 | #> True |
277 | 285 |
|
278 | | -print(g_a.like(g_b)) # False, because of mismatched attributes |
| 286 | +# Returns False, because of mismatched attributes |
| 287 | +print(g_a.like(g_b)) |
279 | 288 | #> False |
280 | 289 |
|
281 | | -print(g_a.like(g_b, exclude={'attributes'})) # True, because we ignore attributes |
| 290 | +# Returns True, because we ignore attributes |
| 291 | +print(g_a.like(g_b, exclude={'attributes'})) |
282 | 292 | #> True |
283 | 293 |
|
284 | | -print(g_a.like(g_a.to_zarr(store, path='g_a'))) # g_a is like its zarr.Group counterpart |
| 294 | +# g_a is like its zarr.Group counterpart |
| 295 | +print(g_a.like(g_a.to_zarr(store, path='g_a'))) |
285 | 296 | #> True |
286 | 297 | ``` |
287 | 298 |
|
288 | 299 | ## Using generic types |
289 | 300 |
|
290 | | -The following examples demonstrate how to specialize `GroupSpec` and `ArraySpec` with type parameters. By specializing `GroupSpec` or `ArraySpec` in this way, python type checkers and Pydantic can type-check elements of a Zarr hierarchy. |
| 301 | +This example shows how to specialize `GroupSpec` and `ArraySpec` with type parameters. By specializing `GroupSpec` or `ArraySpec` in this way, python type checkers and Pydantic can type-check elements of a Zarr hierarchy. |
291 | 302 |
|
292 | 303 | ```python |
293 | 304 | import sys |
@@ -324,7 +335,7 @@ print(SpecificAttrsGroup(attributes={'a': 100, 'b': 100})) |
324 | 335 | #> zarr_version=2 attributes={'a': 100, 'b': 100} members={} |
325 | 336 |
|
326 | 337 | # a Zarr group that only contains arrays -- no subgroups! |
327 | | -# we re-use the Tattributes type variable defined in pydantic_zarr.core |
| 338 | +# we re-use the TAttr type variable defined in pydantic_zarr.core |
328 | 339 | ArraysOnlyGroup = GroupSpec[TAttr, ArraySpec] |
329 | 340 |
|
330 | 341 | try: |
|
0 commit comments