Trait-based xarray weather dataset validator with inline specs
Project description
mlwp-data-specs
Trait-based dataset validator for weather/climate datasets in Zarr format.
Why this was made
To facilitate comparing forecasts from MLWP (Machine Learning Weather Prediction) models this validator implements specifications so that a single well-defined format can be targeted. The motivation for this to allow different groups to share their forecasts in a common format so that general-purpose tooling can be built to examine these forecasts.
Specifically, the specifications is organized around traits (for example, how spatial location is represented) so that downstream tools like mxalign can deterministically map between datasets - or align datasets - that represent traits differently (for example, point-wise observations to gridded data, or the inverse mapping).
In summary, the goals of this project are to:
- make trait-level dataset requirements explicit (
time,space,uncertainty) - keep human-readable spec text and executable validation logic side-by-side
- provide both CLI and Python APIs for local and remote Zarr validation
- publish linkable HTML spec docs directly from the validator code
When should you use this?
Use mlwp-data-specs when you need to verify that a dataset follows agreed MLWP trait conventions, regardless of whether you will run alignment operations.
The intended split is:
mlwp-data-specs: define and validate dataset (xarray.Dataset) structure/metadata contractsmlwp-data-loaders: load datasets from various sources (local, S3, etc.) and provide a common interface to constructxarray.Datasetobject- Uses
mlwp-data-specsto validate datasets at load time. - Can also use your own code to create
xarray.Datasetobjects from scratch or from other formats (e.g., NetCDF, CSV, etc.)
- Uses
mxalignor your own analysis tools: perform alignment/transformation operations on datasets.- Applies
mlwp-data-specsto validate datasets before and after alignment.
- Applies
Typical use cases:
- Upstream reference dataset creation: validate produced reference datasets (observations, NWP forecasts, etc.) at write-time (or just before writing) so they are known to satisfy the shared spec.
- Inference pipelines: validate model output immediately at inference time before publishing/storing results.
- Pre-check before alignment: validate first, then pass conformant datasets to
mxalign. - Downstream consumers that do not align: visualization, QA, and analytics tools can enforce input structure without running alignment logic.
- CI quality gates: fail fast when datasets drift from required trait conventions.
Concrete examples where this is useful include integrating checks in nwp-forecast-zarr-creator and validating upstream inference outputs (for example from ANNA / neural-lam) so downstream tooling, including mxalign, can consume them reliably.
What is this?
mlwp-data-specs validates datasets across three orthogonal trait axes:
time(for example:forecast,observation)space(for example:grid,point)uncertainty(for example:deterministic,ensemble,quantile)
The validator enforces both structural requirements (dimensions/coordinates) and metadata requirements (standard_name, units, etc.).
How specifications are implemented
- Executable trait specs are defined in
src/mlwp_data_specs/specs/traits/. - Each spec module contains inline markdown requirements plus adjacent check function calls.
- Rendered docs pages are generated from those inline specs with
docs/scripts/generate_trait_docs.py.
Code layout
The repository is organized so spec text, checks, and interfaces are separated but composable:
src/mlwp_data_specs/
├── api.py # High-level Python API (validate_dataset)
├── specs/
│ ├── cli.py # CLI entry point (mlwp.validate_dataset_traits)
│ ├── reporting.py # ValidationReport and check registry helpers
│ └── traits/
│ ├── spatial_coordinate.py # Space trait enum + specs + validation wiring
│ ├── time_coordinate.py # Time trait enum + specs + validation wiring
│ └── uncertainty.py # Uncertainty trait enum + specs + validation wiring
├── checks/
│ ├── traits/
│ │ └── _common.py # Shared structural check primitives
│ └── metadata/
│ └── coords.py # standard_name/units/etc checks
Requirements
- The validator MUST check datasets against selected trait specs (
time,space,uncertainty). - Checks MUST cover both structural constraints (dims/coords) and metadata constraints (
standard_name,units, etc.). - Specs MUST remain executable and renderable as documentation.
Interfaces
The validator is expected to provide both interfaces:
- Python API: programmatic validation via
validate_dataset(ds, time=..., space=..., uncertainty=...). - CLI: command-line validation via
mlwp.validate_dataset_traitsfor local/remote datasets and CI usage.
CLI usage
Install locally:
uv sync
Run validation for selected traits:
uv run mlwp.validate_dataset_traits <DATASET_PATH_OR_URL> --time forecast --space grid --uncertainty deterministic
Examples:
# Validate a local Zarr dataset
uv run mlwp.validate_dataset_traits /path/to/dataset.zarr --time forecast --space grid
# Validate a remote S3 dataset with anonymous access
uv run mlwp.validate_dataset_traits s3://bucket/dataset.zarr --time observation --space point --s3-anon
# List available trait values
uv run mlwp.validate_dataset_traits --list-time
uv run mlwp.validate_dataset_traits --list-space
uv run mlwp.validate_dataset_traits --list-uncertainty
Print inline markdown spec text without running validation:
uv run mlwp.validate_dataset_traits --time forecast --print-spec-markdown
Python API usage
Use the high-level API:
import xarray as xr
from mlwp_data_specs import validate_dataset
# Load dataset from local path or remote store
ds = xr.open_zarr("/path/to/dataset.zarr")
report = validate_dataset(
ds,
time="forecast",
space="grid",
uncertainty="deterministic",
)
report.console_print()
if report.has_fails():
raise SystemExit("Dataset validation failed")
Development
Run tests:
uv run python -m pytest
Regenerate docs pages and build site:
uv run python docs/scripts/generate_trait_docs.py
uv run mkdocs build -f docs/mkdocs.yml --strict
Inspirations, prior work
This implementation builds directly on patterns established in:
mlcast-dataset-validator: inline markdown specs + check functions + docs rendering/deployment workflow.mxalign: trait/property model forspace,time, anduncertainty.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mlwp_data_specs-0.1.0.tar.gz.
File metadata
- Download URL: mlwp_data_specs-0.1.0.tar.gz
- Upload date:
- Size: 115.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6038412e3d7b37a406ab5f09b5f0fe035fda7247d307433115e6a38e9a7f9adb
|
|
| MD5 |
c5b3981f997afbcd01ea4096994ed988
|
|
| BLAKE2b-256 |
3ae96e45b713e00ae0b4d24db4f842b6530ca9d31c08ecac455444413faf8628
|
Provenance
The following attestation bundles were made for mlwp_data_specs-0.1.0.tar.gz:
Publisher:
pypi-release.yml on mlwp-tools/mlwp-data-specs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mlwp_data_specs-0.1.0.tar.gz -
Subject digest:
6038412e3d7b37a406ab5f09b5f0fe035fda7247d307433115e6a38e9a7f9adb - Sigstore transparency entry: 1938468076
- Sigstore integration time:
-
Permalink:
mlwp-tools/mlwp-data-specs@370ca01c810664be01d01d1c79148ce939d39984 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mlwp-tools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-release.yml@370ca01c810664be01d01d1c79148ce939d39984 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mlwp_data_specs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mlwp_data_specs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
001f0c496ab268e83b32014a018d570bb19ef70f267fa97be5c4a7b99d4ad606
|
|
| MD5 |
be38b3d210ea2e40313caf937ee478e7
|
|
| BLAKE2b-256 |
87c96dad342576ad1fcfae93c97d8fcc4ebbda742b0114657ff6b0d698e7c748
|
Provenance
The following attestation bundles were made for mlwp_data_specs-0.1.0-py3-none-any.whl:
Publisher:
pypi-release.yml on mlwp-tools/mlwp-data-specs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mlwp_data_specs-0.1.0-py3-none-any.whl -
Subject digest:
001f0c496ab268e83b32014a018d570bb19ef70f267fa97be5c4a7b99d4ad606 - Sigstore transparency entry: 1938468170
- Sigstore integration time:
-
Permalink:
mlwp-tools/mlwp-data-specs@370ca01c810664be01d01d1c79148ce939d39984 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mlwp-tools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-release.yml@370ca01c810664be01d01d1c79148ce939d39984 -
Trigger Event:
release
-
Statement type: