diff --git a/.github/workflows/test-runner.yml b/.github/workflows/test-runner.yml index a96849b3..74f7ce94 100644 --- a/.github/workflows/test-runner.yml +++ b/.github/workflows/test-runner.yml @@ -11,17 +11,14 @@ on: - dev jobs: - test: - name: Execute tests runs-on: ubuntu-latest strategy: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] - - steps: + steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@main @@ -35,7 +32,7 @@ jobs: pytest --mypy stac_validator - name: Run pre-commit - if: matrix.python-version == 3.8 + if: matrix.python-version == 3.10 run: | pre-commit install pre-commit autoupdate diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b4800948..07d8ac25 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,31 +1,29 @@ repos: -- repo: https://github.com/PyCQA/flake8 + - repo: https://github.com/PyCQA/flake8 rev: 7.0.0 hooks: - - id: flake8 -- repo: https://github.com/timothycrosley/isort + - id: flake8 + - repo: https://github.com/timothycrosley/isort rev: 5.13.2 hooks: - - id: isort - args: ["--profile", "black"] -- repo: https://github.com/psf/black + - id: isort + args: ["--profile", "black"] + - repo: https://github.com/psf/black rev: 24.1.1 hooks: - - id: black - language_version: python3.8 -- repo: https://github.com/pre-commit/mirrors-mypy + - id: black + language_version: python3.10 + - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.8.0 hooks: - id: mypy exclude: /tests/ # --strict - args: [ - --no-strict-optional, - --ignore-missing-imports, - --implicit-reexport, - --explicit-package-bases, - ] - additional_dependencies: [ - "types-attrs", - "types-requests" - ] \ No newline at end of file + args: + [ + --no-strict-optional, + --ignore-missing-imports, + --implicit-reexport, + --explicit-package-bases, + ] + additional_dependencies: ["types-attrs", "types-requests"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 236997af..26bc80ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,13 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) ## [Unreleased] +## [v3.4.0] - 2024-10-08 + ### Added - Added ability to validate response from a /collections endpoint [#220](https://github.com/stac-utils/stac-validator/issues/220) - Added mypy to pre-commit config ([#229](https://github.com/stac-utils/stac-validator/pull/224)) +- Support for stac spec version 1.1.0 [#235](https://github.com/stac-utils/stac-validator/pull/235) ## [v3.3.2] - 2023-11-17 @@ -17,7 +20,7 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) - Docstrings ([#224](https://github.com/stac-utils/stac-validator/pull/224)) -### Changed +### Changed - Development dependencies removed from runtime dependency list ([#228](https://github.com/stac-utils/stac-check/pull/109)) @@ -38,13 +41,13 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) ## [v3.2.0] - 2022-09-20 -### Added - +### Added + - Added ability to check local schemas in item extensions https://github.com/stac-utils/stac-validator/pull/215 - Added an example on validating a dictionary https://github.com/stac-utils/stac-validator/pull/215 ### Changed - + - Changed 'ValidationError' error type to 'JSONSchemaValidationError' https://github.com/stac-utils/stac-validator/pull/213 ## [v3.1.0] - 2022-04-28 @@ -83,32 +86,38 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) - References to Python 3.6 ## [v2.5.0] - 2022-03-10 + ### Changed - Split the `--recursive` option into a `--recursive` flag and a `--max-depth` option - Renamed the entry point from `stac_validator` to `stac-validator` ## [v2.4.3] - 2022-03-10 + ### Changed - - Add schema caching +- Add schema caching ## [v2.4.2] - 2022-03-02 + ### Changed - - Loosen pystac version dependency +- Loosen pystac version dependency ## [v2.4.1] - 2022-03-02 + ### Changed - - Loosen stac-check version dependency +- Loosen stac-check version dependency ## [v2.4.0] - 2022-02-02 + ### Added - - Linting option in cli to display stac-check generated information +- Linting option in cli to display stac-check generated information ## [v2.3.0] - 2021-08-31 - 2021-11-28 + ### Added - Added --links option to validate links on format and a valid response @@ -125,6 +134,7 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) - Moved backend to validate.py ## [v2.2.0] - 2021-05-25 + ### Added - Added Support for STAC 1.0.0 @@ -133,17 +143,18 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) ### Changed -- Moved std out to cli so that it doesn't display in pure python applications -- Added Pypi badges to readme - +- Moved std out to cli so that it doesn't display in pure python applications +- Added Pypi badges to readme + ## [v2.1.0] - 2021-05-06 + ### Added - Added more tests for STAC 1.0.0-rc.3 - Added basic support for rc.4 - Add system exit code to CLI. see #144 -### Changed +### Changed - Modified how Lambda CDK is built @@ -160,7 +171,7 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) ### Changed -- Pystac is now only being used to identify stac objects. Jsonschema is being used for all other validation. +- Pystac is now only being used to identify stac objects. Jsonschema is being used for all other validation. - The cli library was changed from Docopt to Click. - Custom validation was updated to allow for local schemas. @@ -196,24 +207,25 @@ The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) - With the newest version - 1.0.0-beta.2 - items will run through jsonchema validation before the PySTAC validation. The reason for this is that jsonschema will give more informative error messages. This should be addressed better in the future. This is not the case with the --recursive option as time can be a concern here with larger collections. - Logging. Various additions were made here depending on the options selected. This was done to help assist people to update their STAC collections. -[Unreleased]: -[v3.3.2]: -[v3.3.1]: -[v3.3.0]: -[v3.2.0]: -[v3.1.0]: -[v3.0.0]: -[v2.5.0]: -[v2.4.3]: -[v2.4.2]: -[v2.4.1]: -[v2.4.0]: -[v2.3.0]: -[v2.2.0]: -[v2.1.0]: -[v2.0.0]: -[v1.0.1]: -[v0.5.0]: -[v0.1.3]: -[v0.1.1]: -[v0.1.0]: +[Unreleased]: https://github.com/sparkgeo/stac-validator/compare/v3.4.0..main +[v3.4.0]: https://github.com/sparkgeo/stac-validator/compare/v3.3.2..v3.4.0 +[v3.3.2]: https://github.com/sparkgeo/stac-validator/compare/v3.3.1..v3.3.2 +[v3.3.1]: https://github.com/sparkgeo/stac-validator/compare/v3.3.0..v3.3.1 +[v3.3.0]: https://github.com/sparkgeo/stac-validator/compare/v3.2.0..v3.3.0 +[v3.2.0]: https://github.com/sparkgeo/stac-validator/compare/v3.1.0..v3.2.0 +[v3.1.0]: https://github.com/sparkgeo/stac-validator/compare/v3.0.0..v3.1.0 +[v3.0.0]: https://github.com/sparkgeo/stac-validator/compare/v2.5.0..v3.0.0 +[v2.5.0]: https://github.com/sparkgeo/stac-validator/compare/v2.4.3..v2.5.0 +[v2.4.3]: https://github.com/sparkgeo/stac-validator/compare/v2.3.0..v2.4.0 +[v2.4.2]: https://github.com/sparkgeo/stac-validator/compare/v2.4.1..v2.4.2 +[v2.4.1]: https://github.com/sparkgeo/stac-validator/compare/v2.4.0..v2.4.1 +[v2.4.0]: https://github.com/sparkgeo/stac-validator/compare/v2.3.0..v2.4.0 +[v2.3.0]: https://github.com/sparkgeo/stac-validator/compare/v2.2.0..v2.3.0 +[v2.2.0]: https://github.com/sparkgeo/stac-validator/compare/v2.1.0..v2.2.0 +[v2.1.0]: https://github.com/sparkgeo/stac-validator/compare/v2.0.0..v2.1.0 +[v2.0.0]: https://github.com/sparkgeo/stac-validator/compare/v1.0.1..v2.0.0 +[v1.0.1]: https://github.com/sparkgeo/stac-validator/compare/v0.5.0..v1.0.1 +[v0.5.0]: https://github.com/sparkgeo/stac-validator/compare/v0.1.3..v0.5.0 +[v0.1.3]: https://github.com/sparkgeo/stac-validator/compare/v0.1.1..v0.1.3 +[v0.1.1]: https://github.com/sparkgeo/stac-validator/compare/v0.1.0..v0.1.1 +[v0.1.0]: https://github.com/sparkgeo/stac-validator/releases/tag/v0.1.0 diff --git a/README.md b/README.md index 7778dc6a..fd0490e8 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,7 @@ [read the docs](https://stac-validator.readthedocs.io/en/latest/) - -## Validate STAC json files against the [STAC spec](https://github.com/radiantearth/stac-spec). - - +## Validate STAC json files against the [STAC spec](https://github.com/radiantearth/stac-spec). ```bash stac-validator https://raw.githubusercontent.com/radiantearth/stac-spec/master/examples/extended-item.json @@ -60,7 +57,6 @@ or for local development pip install -e '.[dev]' ``` - The [Makefile](./Makefile) has convenience commands if Make is installed. ```bash @@ -81,7 +77,8 @@ make help | 1.0.0-rc.3 | | 1.0.0-rc.4 | | 1.0.0 | - +| 1.1.0-beta.1 | +| 1.1.0 | --- @@ -146,7 +143,9 @@ docker run stac-validator https://raw.githubusercontent.com/stac-extensions/proj ``` ## AWS (CDK) + An example [AWS CDK](https://aws.amazon.com/cdk/) deployment is available in [cdk-deployment](./cdk-deployment/README.md) + ```bash cd cdk-deployment cdk diff @@ -201,29 +200,29 @@ print(stac.message) ``` **Dictionary** - + ```python from stac_validator import stac_validator - + stac = stac_validator.StacValidate() stac.validate_dict(dictionary) print(stac.message) ``` **Item Collection** - + ```python from stac_validator import stac_validator - + stac = stac_validator.StacValidate() stac.validate_item_collection_dict(item_collection_dict) print(stac.message) ``` + --- # Testing - ```bash make test # or @@ -233,6 +232,7 @@ pytest -v See the [tests](./tests/test_stac_validator.py) files for examples on different usages. --- + # Additional Examples **--core** @@ -292,7 +292,7 @@ stac-validator https://raw.githubusercontent.com/radiantearth/stac-spec/master/e } ] ``` - + **--recursive** ```bash @@ -324,8 +324,9 @@ stac-validator https://spot-canada-ortho.s3.amazonaws.com/catalog.json --recursi } ] ``` + **--item-collection** ```bash stac-validator https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a/items --item-collection --pages 2 -``` \ No newline at end of file +``` diff --git a/setup.py b/setup.py index b98ca394..d8ef30da 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup -__version__ = "3.3.2" +__version__ = "3.4.0" with open("README.md", "r") as fh: long_description = fh.read() @@ -11,7 +11,7 @@ name="stac_validator", version=__version__, author="James Banting, Jonathan Healy", - author_email="jhealy@sparkgeo.com", + author_email="jonathan.d.healy@gmail.com", description="A package to validate STAC files", license="Apache-2.0", classifiers=[ diff --git a/stac_validator/stac_validator.py b/stac_validator/stac_validator.py index 6dca8db6..899fdd98 100644 --- a/stac_validator/stac_validator.py +++ b/stac_validator/stac_validator.py @@ -18,12 +18,12 @@ def print_update_message(version: str) -> None: None """ click.secho() - if version != "1.0.0": + if version != "1.1.0": click.secho( - f"Please upgrade from version {version} to version 1.0.0!", fg="red" + f"Please upgrade from version {version} to version 1.1.0!", fg="red" ) else: - click.secho("Thanks for using STAC version 1.0.0!", fg="green") + click.secho("Thanks for using STAC version 1.1.0!", fg="green") click.secho() diff --git a/stac_validator/utilities.py b/stac_validator/utilities.py index f07b95b1..5d6a9051 100644 --- a/stac_validator/utilities.py +++ b/stac_validator/utilities.py @@ -14,6 +14,8 @@ "1.0.0-rc.3", "1.0.0-rc.4", "1.0.0", + "1.1.0-beta.1", + "1.1.0", ] diff --git a/tests/test_assets.py b/tests/test_assets.py index 08639212..8c33bb54 100644 --- a/tests/test_assets.py +++ b/tests/test_assets.py @@ -34,10 +34,9 @@ def test_assets_v090(): "s3://cbers-pds/CBERS4/MUX/177/106/CBERS_4_MUX_20181029_177_106_L4/CBERS_4_MUX_20181029_177_106_L4_BAND8.tif", ], "format_invalid": [], - "request_valid": [ - "https://s3.amazonaws.com/cbers-meta-pds/CBERS4/MUX/177/106/CBERS_4_MUX_20181029_177_106_L4/CBERS_4_MUX_20181029_177_106.jpg" - ], + "request_valid": [], "request_invalid": [ + "https://s3.amazonaws.com/cbers-meta-pds/CBERS4/MUX/177/106/CBERS_4_MUX_20181029_177_106_L4/CBERS_4_MUX_20181029_177_106.jpg", "s3://cbers-pds/CBERS4/MUX/177/106/CBERS_4_MUX_20181029_177_106_L4/CBERS_4_MUX_20181029_177_106_L4_BAND6.xml", "s3://cbers-pds/CBERS4/MUX/177/106/CBERS_4_MUX_20181029_177_106_L4/CBERS_4_MUX_20181029_177_106_L4_BAND5.tif", "s3://cbers-pds/CBERS4/MUX/177/106/CBERS_4_MUX_20181029_177_106_L4/CBERS_4_MUX_20181029_177_106_L4_BAND6.tif", diff --git a/tests/test_core.py b/tests/test_core.py index b1781cbb..69d68c77 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -174,3 +174,39 @@ def test_core_item_local_v100(): "validation_method": "core", } ] + + +def test_core_collection_local_v110(): + stac_file = "tests/test_data/v110/collection.json" + stac = stac_validator.StacValidate(stac_file, core=True) + stac.run() + assert stac.message == [ + { + "version": "1.1.0", + "path": "tests/test_data/v110/collection.json", + "schema": [ + "https://schemas.stacspec.org/v1.1.0/collection-spec/json-schema/collection.json" + ], + "valid_stac": True, + "asset_type": "COLLECTION", + "validation_method": "core", + } + ] + + +def test_core_item_local_v110(): + stac_file = "tests/test_data/v110/simple-item.json" + stac = stac_validator.StacValidate(stac_file, core=True) + stac.run() + assert stac.message == [ + { + "version": "1.1.0", + "path": "tests/test_data/v110/simple-item.json", + "schema": [ + "https://schemas.stacspec.org/v1.1.0/item-spec/json-schema/item.json" + ], + "valid_stac": True, + "asset_type": "ITEM", + "validation_method": "core", + } + ] diff --git a/tests/test_data/v110/collection.json b/tests/test_data/v110/collection.json new file mode 100644 index 00000000..5c42d183 --- /dev/null +++ b/tests/test_data/v110/collection.json @@ -0,0 +1,112 @@ +{ + "id": "simple-collection", + "type": "Collection", + "stac_extensions": [ + "https://stac-extensions.github.io/eo/v2.0.0/schema.json", + "https://stac-extensions.github.io/projection/v2.0.0/schema.json", + "https://stac-extensions.github.io/view/v1.0.0/schema.json" + ], + "stac_version": "1.1.0", + "description": "A simple collection demonstrating core catalog fields with links to a couple of items", + "title": "Simple Example Collection", + "keywords": ["simple", "example", "collection"], + "providers": [ + { + "name": "Remote Data, Inc", + "description": "Producers of awesome spatiotemporal assets", + "roles": ["producer", "processor"], + "url": "http://remotedata.io" + } + ], + "extent": { + "spatial": { + "bbox": [ + [ + 172.91173669923782, 1.3438851951615003, 172.95469614953714, + 1.3690476620161975 + ] + ] + }, + "temporal": { + "interval": [["2020-12-11T22:38:32.125Z", "2020-12-14T18:02:31.437Z"]] + } + }, + "license": "CC-BY-4.0", + "summaries": { + "platform": ["cool_sat1", "cool_sat2"], + "constellation": ["ion"], + "instruments": ["cool_sensor_v1", "cool_sensor_v2"], + "gsd": { + "minimum": 0.512, + "maximum": 0.66 + }, + "eo:cloud_cover": { + "minimum": 1.2, + "maximum": 1.2 + }, + "proj:cpde": ["EPSG:32659"], + "view:sun_elevation": { + "minimum": 54.9, + "maximum": 54.9 + }, + "view:off_nadir": { + "minimum": 3.8, + "maximum": 3.8 + }, + "view:sun_azimuth": { + "minimum": 135.7, + "maximum": 135.7 + }, + "statistics": { + "type": "object", + "properties": { + "vegetation": { + "description": "Percentage of pixels that are detected as vegetation, e.g. forests, grasslands, etc.", + "minimum": 0, + "maximum": 100 + }, + "water": { + "description": "Percentage of pixels that are detected as water, e.g. rivers, oceans and ponds.", + "minimum": 0, + "maximum": 100 + }, + "urban": { + "description": "Percentage of pixels that detected as urban, e.g. roads and buildings.", + "minimum": 0, + "maximum": 100 + } + } + } + }, + "links": [ + { + "rel": "root", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + }, + { + "rel": "item", + "href": "./simple-item.json", + "type": "application/geo+json", + "title": "Simple Item" + }, + { + "rel": "item", + "href": "./core-item.json", + "type": "application/geo+json", + "title": "Core Item" + }, + { + "rel": "item", + "href": "./extended-item.json", + "type": "application/geo+json", + "title": "Extended Item" + }, + { + "rel": "self", + "href": "https://raw.githubusercontent.com/radiantearth/stac-spec/v1.1.0/examples/collection.json", + "type": "application/json" + } + ] +} diff --git a/tests/test_data/v110/simple-item.json b/tests/test_data/v110/simple-item.json new file mode 100644 index 00000000..df847546 --- /dev/null +++ b/tests/test_data/v110/simple-item.json @@ -0,0 +1,60 @@ +{ + "stac_version": "1.1.0", + "stac_extensions": [], + "type": "Feature", + "id": "20201211_223832_CS2", + "bbox": [ + 172.91173669923782, 1.3438851951615003, 172.95469614953714, + 1.3690476620161975 + ], + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [172.91173669923782, 1.3438851951615003], + [172.95469614953714, 1.3438851951615003], + [172.95469614953714, 1.3690476620161975], + [172.91173669923782, 1.3690476620161975], + [172.91173669923782, 1.3438851951615003] + ] + ] + }, + "properties": { + "datetime": "2020-12-11T22:38:32.125000Z" + }, + "collection": "simple-collection", + "links": [ + { + "rel": "collection", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + }, + { + "rel": "root", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + }, + { + "rel": "parent", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + } + ], + "assets": { + "visual": { + "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.tif", + "type": "image/tiff; application=geotiff; profile=cloud-optimized", + "title": "3-Band Visual", + "roles": ["visual"] + }, + "thumbnail": { + "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.jpg", + "title": "Thumbnail", + "type": "image/jpeg", + "roles": ["thumbnail"] + } + } +}