From 6a4877f2b35cb39494a347a43d7c3454576dd09a Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Mon, 8 Jul 2024 11:23:52 +0200 Subject: [PATCH 1/3] add request and jsonschema optional dependencies --- README.md | 4 ++++ pyproject.toml | 9 ++++++++- stac_pydantic/extensions.py | 21 ++++++++++++++------- stac_pydantic/scripts/cli.py | 17 ++++++++++++++++- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ec0cba4..d9d4728 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ For more comprehensive schema validation and robust extension support, use [pyst ```shell python -m pip install stac-pydantic + +# or + +python -m pip install stac-pydantic["validation"] ``` For local development: diff --git a/pyproject.toml b/pyproject.toml index 35a2b91..181eece 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,12 @@ keywords=["stac", "pydantic", "validation"] authors=[{ name = "Arturo Engineering", email = "engineering@arturo.ai"}] license= { text = "MIT" } requires-python=">=3.8" -dependencies = ["click>=8.1.7", "pydantic>=2.4.1", "geojson-pydantic>=1.0.0"] +dependencies = [ + "click>=8.1.7", + "pydantic>=2.4.1", + "geojson-pydantic>=1.0.0", + "requests", +] dynamic = ["version", "readme"] [project.scripts] @@ -31,6 +36,8 @@ homepage = "https://github.com/stac-utils/stac-pydantic" repository ="https://github.com/stac-utils/stac-pydantic.git" [project.optional-dependencies] +validation = ["jsonschema>=4.19.1", "requests>=2.31.0"] + dev = [ "pytest>=7.4.2", "pytest-cov>=4.1.0", diff --git a/stac_pydantic/extensions.py b/stac_pydantic/extensions.py index 1818e8c..c1620b5 100644 --- a/stac_pydantic/extensions.py +++ b/stac_pydantic/extensions.py @@ -1,14 +1,20 @@ -import json from functools import lru_cache from typing import Any, Dict, Union -import jsonschema -import requests - from stac_pydantic.catalog import Catalog from stac_pydantic.collection import Collection from stac_pydantic.item import Item +try: + import requests +except ImportError: # pragma: nocover + requests = None # type: ignore + +try: + import jsonschema +except ImportError: # pragma: nocover + jsonschema = None # type: ignore + @lru_cache(maxsize=128) def _fetch_and_cache_schema(url: str) -> dict: @@ -25,12 +31,13 @@ def validate_extensions( Fetch the remote JSON schema, if not already cached, and validate the STAC object against that schema. """ + assert requests is not None, "requests must be installed to validate extensions" + assert jsonschema is not None, "jsonschema must be installed to validate extensions" + if isinstance(stac_obj, dict): stac_dict = stac_obj else: - # can't use `stac_obj.model_dump()` here - # b/c jsonschema expects pure string representations, not python types - stac_dict = json.loads(stac_obj.model_dump_json()) + stac_dict = stac_obj.model_dump(mode="json") try: if stac_dict["stac_extensions"]: diff --git a/stac_pydantic/scripts/cli.py b/stac_pydantic/scripts/cli.py index 76ef706..9941d1b 100644 --- a/stac_pydantic/scripts/cli.py +++ b/stac_pydantic/scripts/cli.py @@ -5,6 +5,16 @@ from stac_pydantic.extensions import validate_extensions from stac_pydantic.item import Item +try: + import requests +except ImportError: # pragma: nocover + requests = None # type: ignore + +try: + import jsonschema +except ImportError: # pragma: nocover + jsonschema = None # type: ignore + @click.group(short_help="Validate STAC") def app() -> None: @@ -16,14 +26,19 @@ def app() -> None: @click.argument("infile") def validate_item(infile: str) -> None: """Validate stac item""" + assert requests is not None, "requests must be installed to validate items" + assert jsonschema is not None, "jsonschema must be installed to validate items" + r = requests.get(infile) r.raise_for_status() + stac_item = r.json() try: - item = Item(**stac_item) + item = Item.model_validate(stac_item) validate_extensions(item, reraise_exception=True) except ValidationError as e: click.echo(str(e)) return + click.echo(f"{infile} is valid") return From bebcd3732634ca1dd2cab2fdc9b85413325edfcd Mon Sep 17 00:00:00 2001 From: Vincent Sarago Date: Mon, 8 Jul 2024 11:25:27 +0200 Subject: [PATCH 2/3] Update pyproject.toml --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 181eece..2c9cdf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,6 @@ dependencies = [ "click>=8.1.7", "pydantic>=2.4.1", "geojson-pydantic>=1.0.0", - "requests", ] dynamic = ["version", "readme"] From ffd9c387dfe7c5edb291c2e8d05d53c1e3fec6ec Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Mon, 8 Jul 2024 11:28:18 +0200 Subject: [PATCH 3/3] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23ea285..b7318be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Unreleased - Cache remote JSON schemas for extensions (#155, @avbentem) +- add `requests` and `jsonschema` in a **validation** optional dependencies (#156, @vincentsarago) ## 3.1.0 (2024-05-21)