Skip to content

Commit

Permalink
Include href when schema resolution fails (#1263)
Browse files Browse the repository at this point in the history
* fix(spell): test name

* feat: report href when failing to fetch schema
  • Loading branch information
gadomski authored Oct 13, 2023
1 parent e456289 commit 59d1868
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
### Changed

- `validate_all` now accepts a `STACObject` (in addition to accepting a dict, which is now deprecated), but prohibits supplying a value for `href`, which must be supplied _only_ when supplying an object as a dict. Once `validate_all` removes support for an object as a dict, the `href` parameter will also be removed. ([#1246](https://github.com/stac-utils/pystac/pull/1246))
- Report `href` when schema url resolution fails ([#1263](https://github.com/stac-utils/pystac/pull/1263))

### Fixed

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ test = [
"pytest-mock~=3.10",
"pytest-recording~=0.13.0",
"pytest~=7.3",
"requests-mock~=1.11",
"ruff==0.0.292",
"types-html5lib~=1.1",
"types-orjson~=3.6",
Expand Down
4 changes: 4 additions & 0 deletions pystac/validation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from pystac.stac_object import STACObjectType
from pystac.utils import make_absolute_href
from pystac.validation.schema_uri_map import OldExtensionSchemaUriMap
from pystac.validation.stac_validator import GetSchemaError

if TYPE_CHECKING:
from pystac.stac_object import STACObject
Expand Down Expand Up @@ -245,3 +246,6 @@ def set_validator(validator: STACValidator) -> None:
validation.
"""
RegisteredValidator.set_validator(validator)


__all__ = ["GetSchemaError"]
12 changes: 11 additions & 1 deletion pystac/validation/stac_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
logger = logging.getLogger(__name__)


class GetSchemaError(Exception):
"""Raised when unable to fetch a schema."""

def __init__(self, href: str, error: Exception) -> None:
super().__init__(f"Error when fetching schema {href}: {error}")


class STACValidator(ABC):
"""STACValidator defines methods for validating STAC
JSON. Implementations define methods for validating core objects and extension.
Expand Down Expand Up @@ -155,7 +162,10 @@ def __init__(self, schema_uri_map: Optional[SchemaUriMap] = None) -> None:

def _get_schema(self, schema_uri: str) -> dict[str, Any]:
if schema_uri not in self.schema_cache:
s = json.loads(pystac.StacIO.default().read_text(schema_uri))
try:
s = json.loads(pystac.StacIO.default().read_text(schema_uri))
except Exception as error:
raise GetSchemaError(schema_uri, error) from error
self.schema_cache[schema_uri] = s
id_field = "$id" if "$id" in s else "id"
if not s[id_field].startswith("http"):
Expand Down
15 changes: 14 additions & 1 deletion tests/validation/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@

import jsonschema
import pytest
from requests_mock import Mocker

import pystac
import pystac.validation
from pystac.cache import CollectionCache
from pystac.serialization.common_properties import merge_common_properties
from pystac.utils import get_opt
from pystac.validation import GetSchemaError
from tests.utils import TestCases
from tests.utils.test_cases import ExampleInfo

Expand Down Expand Up @@ -188,10 +190,21 @@ def test_catalog_latest_version_uses_local(catalog: pystac.Catalog) -> None:


@pytest.mark.block_network
def test_collection_latest_versio_uses_localn(collection: pystac.Collection) -> None:
def test_collection_latest_version_uses_local(collection: pystac.Collection) -> None:
assert collection.validate()


@pytest.mark.block_network
def test_item_latest_version_uses_local(item: pystac.Item) -> None:
assert item.validate()


def test_404_schema_url(requests_mock: Mocker, item: pystac.Item) -> None:
requests_mock.get(
"http://pystac-extensions.test/a-fake-schema.json", status_code=404
)
item.stac_extensions = ["http://pystac-extensions.test/a-fake-schema.json"]
with pytest.raises(
GetSchemaError, match="http://pystac-extensions.test/a-fake.schema.json"
):
item.validate()

0 comments on commit 59d1868

Please sign in to comment.