Skip to content

Commit

Permalink
docs: fix broken link and prose
Browse files Browse the repository at this point in the history
  • Loading branch information
d-v-b committed Mar 19, 2024
1 parent 392ff88 commit d36c1e2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Static typing and runtime validation for Zarr hierachies.

## Overview

`pydantic-zarr` expresses data stored in the [zarr](https://zarr.readthedocs.io/en/stable/) format with [Pydantic](https://docs.pydantic.dev/1.10/). Specifically, `pydantic-zarr` encodes Zarr groups and arrays as [Pydantic models](https://docs.pydantic.dev/1.10/usage/models/). These models are useful for formalizing the structure of Zarr hierarchies, type-checking Zarr hierarchies, and runtime validation for Zarr-based data.
`pydantic-zarr` expresses data stored in the [Zarr](https://zarr.readthedocs.io/en/stable/) format with [Pydantic](https://docs.pydantic.dev/1.10/). Specifically, `pydantic-zarr` encodes Zarr groups and arrays as [Pydantic models](https://docs.pydantic.dev/1.10/usage/models/). These models are useful for formalizing the structure of Zarr hierarchies, type-checking Zarr hierarchies, and runtime validation for Zarr-based data.


```python
Expand Down Expand Up @@ -86,5 +86,5 @@ Zarr arrays are represented by the `ArraySpec` class, which has a similar `attri

`GroupSpec` and `ArraySpec` are both [generic models](https://docs.pydantic.dev/1.10/usage/models/#generic-models). `GroupSpec` takes two type parameters, the first specializing the type of `GroupSpec.attributes`, and the second specializing the type of the *values* of `GroupSpec.members` (the keys of `GroupSpec.members` are always strings). `ArraySpec` only takes one type parameter, which specializes the type of `ArraySpec.attributes`.

Examples using this generic typing functionality can be found in the [usage guide](usage.md#using-generic-types).
Examples using this generic typing functionality can be found in the [usage guide](usage_zarr_v2.md#using-generic-types).

41 changes: 26 additions & 15 deletions docs/usage_zarr_v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,53 +241,64 @@ print(GroupSpec.from_flat(tree).model_dump())

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.

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.
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.

```python
from pydantic_zarr.v2 import ArraySpec, GroupSpec
import zarr
arr_a = ArraySpec(shape=(1,), dtype='uint8', chunks=(1,))
arr_b = ArraySpec(shape=(2,), dtype='uint8', chunks=(1,)) # array with different shape
# make an array with a different shape
arr_b = ArraySpec(shape=(2,), dtype='uint8', chunks=(1,))

print(arr_a.like(arr_b)) # False, because of mismatched shape
# Returns False, because of mismatched shape
print(arr_a.like(arr_b))
#> False

print(arr_a.like(arr_b, exclude={'shape'})) # True, because we exclude shape.
# Returns True, because we exclude shape.
print(arr_a.like(arr_b, exclude={'shape'}))
#> True

# `ArraySpec.like` will convert a zarr.Array to ArraySpec
store = zarr.MemoryStore()
arr_a_stored = arr_a.to_zarr(store, path='arr_a') # this is a zarr.Array
# This is a zarr.Array
arr_a_stored = arr_a.to_zarr(store, path='arr_a')

print(arr_a.like(arr_a_stored)) # arr_a is like the zarr.Array version of itself
# arr_a is like the zarr.Array version of itself
print(arr_a.like(arr_a_stored))
#> True

print(arr_b.like(arr_a_stored)) # False, because of mismatched shape
# Returns False, because of mismatched shape
print(arr_b.like(arr_a_stored))
#> False

print(arr_b.like(arr_a_stored, exclude={'shape'})) # True, because we exclude shape.
# Returns True, because we exclude shape.
print(arr_b.like(arr_a_stored, exclude={'shape'}))
#> True

# the same thing thing for groups
# The same thing, but for groups
g_a = GroupSpec(attributes={'foo': 10}, members={'a': arr_a, 'b': arr_b})
g_b = GroupSpec(attributes={'foo': 11}, members={'a': arr_a, 'b': arr_b})

print(g_a.like(g_a)) # g_a is like itself
# g_a is like itself
print(g_a.like(g_a))
#> True

print(g_a.like(g_b)) # False, because of mismatched attributes
# Returns False, because of mismatched attributes
print(g_a.like(g_b))
#> False

print(g_a.like(g_b, exclude={'attributes'})) # True, because we ignore attributes
# Returns True, because we ignore attributes
print(g_a.like(g_b, exclude={'attributes'}))
#> True

print(g_a.like(g_a.to_zarr(store, path='g_a'))) # g_a is like its zarr.Group counterpart
# g_a is like its zarr.Group counterpart
print(g_a.like(g_a.to_zarr(store, path='g_a')))
#> True
```

## Using generic types

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.
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.

```python
import sys
Expand Down Expand Up @@ -324,7 +335,7 @@ print(SpecificAttrsGroup(attributes={'a': 100, 'b': 100}))
#> zarr_version=2 attributes={'a': 100, 'b': 100} members={}

# a Zarr group that only contains arrays -- no subgroups!
# we re-use the Tattributes type variable defined in pydantic_zarr.core
# we re-use the TAttr type variable defined in pydantic_zarr.core
ArraysOnlyGroup = GroupSpec[TAttr, ArraySpec]

try:
Expand Down

0 comments on commit d36c1e2

Please sign in to comment.