Skip to content

Commit

Permalink
validate example STAC Collection/Item against JSON-schema
Browse files Browse the repository at this point in the history
  • Loading branch information
fmigneault committed Mar 27, 2024
1 parent d9ff4a9 commit d9d8630
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 54 deletions.
58 changes: 58 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from typing import cast

import json
import pytest
import pystac
from dateutil.parser import parse as dt_parse

from pystac_ml_aoi.extensions.ml_aoi import ML_AOI_SCHEMA_PATH, ML_AOI_SCHEMA_URI


@pytest.fixture(scope="session", name="stac_validator", autouse=True)
def make_stac_ml_aoi_validator(
request: pytest.FixtureRequest,
) -> pystac.validation.stac_validator.JsonSchemaSTACValidator:
"""
Update the :class:`pystac.validation.RegisteredValidator` with the local ML-AOI JSON schema definition.
Because the schema is *not yet* uploaded to the expected STAC schema URI,
any call to :func:`pystac.validation.validate` or :meth:`pystac.stac_object.STACObject.validate` results
in ``GetSchemaError`` when the schema retrieval is attempted by the validator. By adding the schema to the
mapping beforehand, remote resolution can be bypassed temporarily.
"""
validator = pystac.validation.RegisteredValidator.get_validator()
validator = cast(pystac.validation.stac_validator.JsonSchemaSTACValidator, validator)
validation_schema = json.loads(pystac.StacIO.default().read_text(ML_AOI_SCHEMA_PATH))
validator.schema_cache[ML_AOI_SCHEMA_URI] = validation_schema
pystac.validation.RegisteredValidator.set_validator(validator) # apply globally to allow 'STACObject.validate()'
return validator


@pytest.fixture(scope="function", name="collection")
def make_base_stac_collection() -> pystac.Collection:
"""
Example reference STAC Collection taken from:
- https://github.com/stac-extensions/ml-aoi/blob/main/examples/collection_EuroSAT-subset-train.json
- https://github.com/ai-extensions/stac-data-loader/blob/main/data/EuroSAT/stac/subset/train/collection.json
The ML-AOI fields are to be extended by the various unit test functions.
"""
ext = pystac.Extent(
spatial=pystac.SpatialExtent(
bboxes=[[-7.882190080512502, 37.13739173208318, 27.911651652899923, 58.21798141355221]],
),
temporal=pystac.TemporalExtent(
intervals=[dt_parse("2015-06-27T10:25:31.456Z"), dt_parse("2017-06-14T00:00:00Z")],
),
)
col = pystac.Collection(
id="EuroSAT-subset-train",
description=(
"EuroSAT dataset with labeled annotations for land-cover classification and associated imagery. "
"This collection represents samples part of the train split set for training machine learning algorithms."
),
extent=ext,
license="MIT",
catalog_type=pystac.CatalogType.ABSOLUTE_PUBLISHED,
)
return col
37 changes: 37 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Tests all files in the `examples` directory against the JSON-schema.
"""
import glob
import os

import pystac
import pytest

from pystac_ml_aoi.extensions.ml_aoi import ML_AOI_SCHEMA_URI

CUR_DIR = os.path.dirname(os.path.realpath(__file__))
ROOT_DIR = os.path.dirname(CUR_DIR)
EXAMPLES_DIR = os.path.join(ROOT_DIR, "examples")


@pytest.mark.parametrize("file_path", glob.glob(f"{EXAMPLES_DIR}/**/collection_*.json", recursive=True))
def test_stac_collection_examples(
file_path: str,
stac_validator: pystac.validation.stac_validator.JsonSchemaSTACValidator,
) -> None:
col = pystac.Collection.from_file(file_path)
valid_schemas = col.validate(validator=stac_validator)
assert ML_AOI_SCHEMA_URI in valid_schemas


@pytest.mark.parametrize("file_path", glob.glob(f"{EXAMPLES_DIR}/**/item_*.geojson", recursive=True))
def test_stac_item_examples(
file_path: str,
stac_validator: pystac.validation.stac_validator.JsonSchemaSTACValidator,
) -> None:
item = pystac.Item.from_file(file_path)
valid_schemas = item.validate(validator=stac_validator)
assert ML_AOI_SCHEMA_URI in valid_schemas
54 changes: 0 additions & 54 deletions tests/test_pystac_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@
"""
Test functionalities provided by :class:`MLAOI_Extension`.
"""
import json
import unittest
import pystac
import pytest
import requests
import shapely
from dateutil.parser import parse as dt_parse
from typing import cast

from pystac.extensions.label import LabelExtension, LabelTask, LabelType
from pystac_ml_aoi.extensions.ml_aoi import (
ML_AOI_Extension,
ML_AOI_CollectionExtension,
ML_AOI_ItemExtension,
ML_AOI_SCHEMA_PATH,
ML_AOI_SCHEMA_URI,
ML_AOI_Role,
ML_AOI_Split,
Expand All @@ -40,56 +36,6 @@
)


@pytest.fixture(scope="session", name="stac_validator", autouse=True)
def make_stac_ml_aoi_validator(
request: pytest.FixtureRequest,
) -> pystac.validation.stac_validator.JsonSchemaSTACValidator:
"""
Update the :class:`pystac.validation.RegisteredValidator` with the local ML-AOI JSON schema definition.
Because the schema is *not yet* uploaded to the expected STAC schema URI,
any call to :func:`pystac.validation.validate` or :meth:`pystac.stac_object.STACObject.validate` results
in ``GetSchemaError`` when the schema retrieval is attempted by the validator. By adding the schema to the
mapping beforehand, remote resolution can be bypassed temporarily.
"""
validator = pystac.validation.RegisteredValidator.get_validator()
validator = cast(pystac.validation.stac_validator.JsonSchemaSTACValidator, validator)
validation_schema = json.loads(pystac.StacIO.default().read_text(ML_AOI_SCHEMA_PATH))
validator.schema_cache[ML_AOI_SCHEMA_URI] = validation_schema
pystac.validation.RegisteredValidator.set_validator(validator) # apply globally to allow 'STACObject.validate()'
return validator


@pytest.fixture(scope="function", name="collection")
def make_base_stac_collection() -> pystac.Collection:
"""
Example reference STAC Collection taken from:
- https://github.com/stac-extensions/ml-aoi/blob/main/examples/collection_EuroSAT-subset-train.json
- https://github.com/ai-extensions/stac-data-loader/blob/main/data/EuroSAT/stac/subset/train/collection.json
The ML-AOI fields are to be extended by the various unit test functions.
"""
ext = pystac.Extent(
spatial=pystac.SpatialExtent(
bboxes=[[-7.882190080512502, 37.13739173208318, 27.911651652899923, 58.21798141355221]],
),
temporal=pystac.TemporalExtent(
intervals=[dt_parse("2015-06-27T10:25:31.456Z"), dt_parse("2017-06-14T00:00:00Z")],
),
)
col = pystac.Collection(
id="EuroSAT-subset-train",
description=(
"EuroSAT dataset with labeled annotations for land-cover classification and associated imagery. "
"This collection represents samples part of the train split set for training machine learning algorithms."
),
extent=ext,
license="MIT",
catalog_type=pystac.CatalogType.ABSOLUTE_PUBLISHED,
)
return col


@pytest.fixture(scope="function", name="item")
def make_base_stac_item() -> pystac.Item:
"""
Expand Down

0 comments on commit d9d8630

Please sign in to comment.