pydantic-tensorstore
Type-safe, validated TensorStore specifications with Pydantic
Motivation
TensorStore is an exceptional C++ and Python library for reading and writing large multi-dimensional arrays. It supports numerous storage formats (Zarr, N5, Neuroglancer Precomputed) and backends (local files, cloud storage, memory), making it incredibly powerful for scientific computing and data analysis.
However, TensorStore has some pain points that this library attempts to address:
- Poor type hinting: TensorStore specifications are typically created as dictionaries with minimal type information, making it difficult to know what fields are available or required
- Complex documentation: Creating proper TensorStore JSON spec objects often requires constantly referencing web documentation to understand the various options and their relationships
- No IDE support: Without proper types, IDEs can't provide autocomplete, validation, or refactoring support
pydantic-tensorstore solves these issues by providing:
- Full type safety with Pydantic v2 models
- Excellent IDE support with autocomplete and validation
- Clear, actionable error messages when specifications are invalid
- Runtime validation with detailed error reporting
- Seamless conversion to native TensorStore specs
- Documentation embedded in the type system (field descriptions state TensorStore's defaults)
Quick Example
Instead of wrestling with raw dictionaries:
# Raw TensorStore (no types, no validation, no IDE support)
import tensorstore as ts
spec = {
"driver": "zarr",
"kvstore": {"driver": "file", "path": "/data/"},
"metadata": {
"chunks": [64, 64],
"compressor": {"id": "blosc", "cname": "lz4", "clevel": 5},
"dtype": "<f4", # Is this right? 🤔
},
}
# Hope it works! 🤞
Use type-safe, validated specifications with IDE autocompletion:
# pydantic-tensorstore (full types, validation, IDE support)
import pydantic_tensorstore as pts
spec = pts.Zarr2Spec(
kvstore=pts.MemoryKvStore(),
metadata=pts.Zarr2Metadata(
chunks=[64, 64],
compressor=pts.Zarr2CompressorBlosc(cname="lz4", clevel=5),
dtype="<f4",
),
)
# Convert to native TensorStore when needed
ts_spec = spec.to_tensorstore() # requires tensorstore to be installed
To cast any dict (or JSON string, or tensorstore.Spec) to a validated spec:
from pydantic_tensorstore import validate_spec
validated_spec = validate_spec(raw_dict)
Installation
pip install pydantic-tensorstore
# with a compatible version of tensorstore installed for .to_tensorstore() support
pip install 'pydantic-tensorstore[tensorstore]'
TensorStore compatibility
TensorStore's JSON spec is defined by the
schema files in its repository.
The models here are checked field-by-field against those files for a single
pinned release, exposed as pydantic_tensorstore.TENSORSTORE_VERSION.
- Verified against: tensorstore
0.1.85(TENSORSTORE_VERSION) - Tested with: tensorstore
>= 0.1.68(MIN_TENSORSTORE_VERSION). CI runs the full suite against the oldest, a midpoint, the pinned, and the newest release. Nearly everything the models can express already works on 0.1.68; the dozen fields and data types TensorStore added later carry asincemarker. - Version check:
spec.required_tensorstore_version()reports the oldest release a spec needs, andto_tensorstore()raisesUnsupportedTensorStoreVersionErrornaming the offending fields when the installed tensorstore is older (passcheck_version=Falseto skip). - Drift: a weekly CI job re-checks the models against the newest tensorstore release and opens an issue when something changes.
>>> spec = pts.Zarr3Spec(kvstore="memory://", open_as_void=True)
>>> spec.required_tensorstore_version()
'0.1.85'
>>> spec.to_tensorstore() # with tensorstore 0.1.68 installed
UnsupportedTensorStoreVersionError: installed tensorstore 0.1.68 does not support:
open_as_void: requires tensorstore >= 0.1.85
Two design rules keep the models forward-compatible:
- Optional fields default to
None, meaning "let TensorStore decide". TensorStore's own default is documented in the field description. Dumping a spec emits only the fields you set (an explicitNoneis kept asnull, since TensorStore givesnullmeaning for e.g.compressor). - KvStore URLs pass through.
file://,memory://,s3://,gs://andhttp(s)://URLs are parsed into models; any other URL string (including pipelines such as"memory://a.zip|zip:") is kept verbatim and handed to TensorStore unchanged.
Known differences from TensorStore
A few deliberate or documented divergences, so they don't surprise you:
- Partial specs are rejected. TensorStore accepts
{"driver": "zarr3"}with nokvstore, to be filled in later viats.Spec.update()or anopen()argument. The models requirekvstore(andcast'sdtype), trading that pattern for a clear "you forgot the kvstore" error. Specs produced by a real store always include it. - Non-finite numbers become strings in JSON.
model_dump_json()writes"NaN","Infinity"and"-Infinity", which TensorStore reads back as floats. Python-modemodel_dump()keeps the float. Note that re-validating that JSON gives you the string back, sincefill_valueis untyped. schemais spelledschema_on the model, becauseschemacollides with a Pydantic attribute. Both work at runtime, but mypy only acceptsschema_=;validate_spec()takes plain"schema"in a dict either way.- Arrays are not silently truncated.
ArraySpecrefuses adtypethat would lose data, rather than quietly rounding.
Coverage
Every driver, kvstore, and context resource documented in tensorstore
TENSORSTORE_VERSION has a model.
| Kind | Models |
|---|---|
| Chunked drivers | Zarr2Spec (zarr/zarr2), Zarr3Spec, N5Spec, NeuroglancerPrecomputedSpec |
| Image drivers | AvifSpec, BmpSpec, JpegSpec, PngSpec, TiffSpec, WebpSpec |
| Other drivers | ArraySpec, AutoSpec, CastSpec, DownsampleSpec, JsonSpec, StackSpec |
| KvStores | FileKvStore, MemoryKvStore, S3KvStore, GCSKvStore, HTTPKvStore, TsGrpcKvStore |
| KvStore adapters | OcdbtKvStore, ZipKvStore, KvStackKvStore, NeuroglancerUint64ShardedKvStore, Zarr3ShardingIndexedKvStore |
| Codecs | Zarr2Codec, Zarr3Codec (+ every zarr3 codec), N5Codec, NeuroglancerPrecomputedCodec |
| Core | Schema, ChunkLayout, IndexDomain, IndexTransform, Context (+ every context resource), Unit |
TensorStoreSpec and KvStore are discriminated unions over all of the above;
validate_spec() and validate_kvstore() parse into them.
Development
Tests compare the models against the vendored schema files in tests/ts_schema/
and, when tensorstore is installed, round-trip every spec through
tensorstore.Spec. To move to a newer tensorstore release:
uv run scripts/update_ts_schema.py --latest # refresh tests/ts_schema/
# bump TENSORSTORE_VERSION in src/pydantic_tensorstore/__init__.py
uv run pytest tests/test_schema_conformance.py # shows exactly what changed
Release files for pydantic-tensorstore 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydantic_tensorstore-0.1.0.tar.gz | 87.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydantic_tensorstore-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 139.9 kB
Release files / pydantic_tensorstore-0.1.0.tar.gz
| Download URL | pydantic_tensorstore-0.1.0.tar.gz |
|---|---|
| Size | 87.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0c2e7d07e2b8392f683aaf42d457f1352dbf5f9505567c666675c5efa350e954
|
|
BLAKE2b-256 checksum How to use checksums |
490a08557f34f75e1e732deeb1acb28ff9ed479cd6f6d58891618d1881dcc6ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / pydantic_tensorstore-0.1.0-py3-none-any.whl
| Download URL | pydantic_tensorstore-0.1.0-py3-none-any.whl |
|---|---|
| Size | 52.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a5bed3708bf91acebc8aff0d34ff063f4edb3ad38466ceb630161be0bcf3d9dd
|
|
BLAKE2b-256 checksum How to use checksums |
1d0b86fba3650650b2059dd0c22b47dcbff9deb0c8c084d20844be58fa03a4fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency log