diff --git a/pyproject.toml b/pyproject.toml index 3b92193..7a59460 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,9 @@ dev = [ "pre-commit>=4.0.0", "ipython>=9.11.0", "pytest>=9.0.2", + "pooch>=1.9.0", ] test = [ "mxalign", + "pooch", ] diff --git a/src/mlwp_data_loaders/loaders/harp/obstable.py b/src/mlwp_data_loaders/loaders/harp/obstable.py index fe54367..fc1cd76 100644 --- a/src/mlwp_data_loaders/loaders/harp/obstable.py +++ b/src/mlwp_data_loaders/loaders/harp/obstable.py @@ -92,6 +92,14 @@ def load_dataset( altitude=("code", alt_values), ) + ds.coords["valid_time"].attrs["standard_name"] = "time" + ds.coords["latitude"].attrs.update( + {"standard_name": "latitude", "units": "degrees_north"} + ) + ds.coords["longitude"].attrs.update( + {"standard_name": "longitude", "units": "degrees_east"} + ) + return ds.rename_dims({"code": "point_index"}).transpose( "valid_time", "point_index" ) diff --git a/tests/test_harp_obstable_integration.py b/tests/test_harp_obstable_integration.py new file mode 100644 index 0000000..43d6616 --- /dev/null +++ b/tests/test_harp_obstable_integration.py @@ -0,0 +1,54 @@ +"""Integration tests for the built-in ``harp.obstable`` loader.""" + +from __future__ import annotations + +import pooch +import pytest +from mlwp_data_specs import validate_dataset + +from mlwp_data_loaders.api import load_dataset +from mlwp_data_loaders.core import get_dataset_traits_from_loader +from mlwp_data_loaders.mxalign_api import validate_dataset_with_mxalign + +HARP_DATA_URL = "https://raw.githubusercontent.com/harphub/harpData/master/inst/OBSTABLE/OBSTABLE_2019.sqlite" +HARP_DATA_HASH = "bdab991c287a41871488456d1a9d697942aa3a612800a88264defa312a9d637b" +LOADER = "mlwp_data_loaders.loaders.harp.obstable" + + +@pytest.fixture(scope="module") +def obstable_path() -> str: + """Download and cache the test SQLite dataset.""" + return pooch.retrieve( + url=HARP_DATA_URL, + known_hash=HARP_DATA_HASH, + ) + + +def test_load_dataset_opens_harp_obstable(obstable_path: str) -> None: + """The harp.obstable loader can open and validate the sample SQLite file.""" + ds = load_dataset( + obstable_path, + loader=LOADER, + ) + + traits = get_dataset_traits_from_loader(LOADER) + + report_mxalign = validate_dataset_with_mxalign( + ds, + time=traits.get("time_profile"), + space=traits.get("space_profile"), + uncertainty=traits.get("uncertainty_profile"), + ) + if report_mxalign.has_fails(): + report_mxalign.console_print() + assert not report_mxalign.has_fails() + + report_specs = validate_dataset( + ds, + time=traits.get("time_profile"), + space=traits.get("space_profile"), + uncertainty=traits.get("uncertainty_profile"), + ) + if report_specs.has_fails(): + report_specs.console_print() + assert not report_specs.has_fails() diff --git a/uv.lock b/uv.lock index 9e19733..addea55 100644 --- a/uv.lock +++ b/uv.lock @@ -1435,11 +1435,13 @@ test = [ [package.dev-dependencies] dev = [ { name = "ipython" }, + { name = "pooch" }, { name = "pre-commit" }, { name = "pytest" }, ] test = [ { name = "mxalign" }, + { name = "pooch" }, ] [package.metadata] @@ -1459,10 +1461,14 @@ provides-extras = ["test"] [package.metadata.requires-dev] dev = [ { name = "ipython", specifier = ">=9.11.0" }, + { name = "pooch", specifier = ">=1.9.0" }, { name = "pre-commit", specifier = ">=4.0.0" }, { name = "pytest", specifier = ">=9.0.2" }, ] -test = [{ name = "mxalign", git = "https://github.com/mlwp-tools/mxalign?rev=e2232d93275c7508897a7ddb0cce8b508665f24c" }] +test = [ + { name = "mxalign", git = "https://github.com/mlwp-tools/mxalign?rev=e2232d93275c7508897a7ddb0cce8b508665f24c" }, + { name = "pooch" }, +] [[package]] name = "mlwp-data-specs" @@ -1994,6 +2000,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pooch" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "platformdirs" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/43/85ef45e8b36c6a48546af7b266592dc32d7f67837a6514d111bced6d7d75/pooch-1.9.0.tar.gz", hash = "sha256:de46729579b9857ffd3e741987a2f6d5e0e03219892c167c6578c0091fb511ed", size = 61788, upload-time = "2026-01-30T19:15:09.649Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl", hash = "sha256:f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b", size = 67175, upload-time = "2026-01-30T19:15:08.36Z" }, +] + [[package]] name = "pre-commit" version = "4.5.1"