Skip to content

Commit

Permalink
Merge pull request #94 from stac-utils/in_memory
Browse files Browse the repository at this point in the history
Allow for linting in-memory dictionaries
  • Loading branch information
jonhealy1 authored Nov 29, 2022
2 parents a3a8c39 + 8ebdc01 commit 4a8c71d
Show file tree
Hide file tree
Showing 5 changed files with 444 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is (loosely) based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased
## Added
- Ability to lint dictionaries https://github.com/stac-utils/stac-check/pull/94
## Fixed
- Fixed the check_catalog_file_name() method to only work on static catalogs https://github.com/stac-utils/stac-check/pull/94

## [v1.3.1] - 2022-10-05
## Changed
Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ or for local development
`$ pip install -e .`

---
### Usage
### CLI Usage
```
Usage: stac-check [OPTIONS] FILE
Expand All @@ -34,7 +34,18 @@ $ make build
$ make shell
```
---
### Examples
### Lint Dictionary

```
from stac_linter.lint import Linter
linter = Linter(dict)
for k,v in linter.create_best_practices_dict().items():
print(k,":",v)
```
---
### CLI Examples

``` stac-check https://raw.githubusercontent.com/stac-utils/pystac/main/tests/data-files/examples/0.9.0/collection-spec/examples/landsat-collection.json --recursive ```
```
Expand Down Expand Up @@ -208,4 +219,4 @@ Validation error message:
'id' is a required property of the root of the STAC object

This object has 5 links
</pre>
</pre>
57 changes: 38 additions & 19 deletions stac_check/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
import os
from dataclasses import dataclass
import requests
from typing import Optional
from typing import Optional, Union
from dotenv import load_dotenv
import pkg_resources

load_dotenv()

@dataclass
class Linter:
item: str
item: Union[str, dict] # url, file name, or dictionary
config_file: Optional[str] = None
assets: bool = False
links: bool = False
Expand All @@ -38,7 +38,7 @@ def __post_init__(self):
self.invalid_link_request = self.check_links_assets(10, "links", "request") if self.links else None
self.schema = self.message["schema"] if "schema" in self.message else []
self.object_id = self.data["id"] if "id" in self.data else ""
self.file_name = os.path.basename(self.item).split('.')[0]
self.file_name = self.get_asset_name(self.item)
self.best_practices_msg = self.create_best_practices_msg()

@staticmethod
Expand All @@ -57,24 +57,41 @@ def parse_config(config_file):

return default_config

def get_asset_name(self, file):
if isinstance(file, str):
return os.path.basename(file).split('.')[0]
else:
return file["id"]

def load_data(self, file):
if is_valid_url(file):
resp = requests.get(file)
data = resp.json()
if isinstance(file, str):
if is_valid_url(file):
resp = requests.get(file)
data = resp.json()
else:
with open(file) as json_file:
data = json.load(json_file)
return data
else:
with open(file) as json_file:
data = json.load(json_file)
return data
return file

def validate_file(self, file):
stac = StacValidate(file, links=self.links, assets=self.assets)
stac.run()
if isinstance(file, str):
stac = StacValidate(file, links=self.links, assets=self.assets)
stac.run()
else:
stac = StacValidate()
stac.validate_dict(file)
return stac.message[0]

def recursive_validation(self, file):
if self.recursive:
stac = StacValidate(file, recursive=True, max_depth=self.max_depth)
stac.run()
if isinstance(file, str):
stac = StacValidate(file, recursive=True, max_depth=self.max_depth)
stac.run()
else:
stac = StacValidate(recursive=True, max_depth=self.max_depth)
stac.validate_dict(file)
return stac.message

def set_update_message(self):
Expand Down Expand Up @@ -179,11 +196,13 @@ def check_item_id_file_name(self):
else:
return True

def check_catalog_id_file_name(self):
if self.asset_type == "CATALOG" and self.file_name != 'catalog':
return False
elif self.asset_type == "COLLECTION" and self.file_name != 'collection':
return False
def check_catalog_file_name(self):
if isinstance(self.item, str) and ".json" in self.item:
if self.asset_type == "CATALOG" and 'catalog.json' not in self.item:
return False
elif self.asset_type == "COLLECTION" and 'collection.json' not in self.item:
return False
return True
else:
return True

Expand Down Expand Up @@ -211,7 +230,7 @@ def create_best_practices_dict(self):
best_practices_dict["check_item_id"] = [msg_1]

# best practices - collection and catalog file names should be collection.json and catalog.json
if not self.check_catalog_id_file_name() and config["catalog_id_file_name"] == True:
if self.check_catalog_file_name() == False and config["catalog_id_file_name"] == True:
msg_1 = f"Object should be called '{self.asset_type.lower()}.json' not '{self.file_name}.json'"
best_practices_dict["check_catalog_id"] = [msg_1]

Expand Down
141 changes: 141 additions & 0 deletions test_dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# from stac_check.lint import Linter

# file = {
# "stac_version": "1.0.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": {
# "title": "Core Item",
# "description": "A sample STAC Item that includes examples of all common metadata",
# "datetime": None,
# "start_datetime": "2020-12-11T22:38:32.125Z",
# "end_datetime": "2020-12-11T22:38:32.327Z",
# "created": "2020-12-12T01:48:13.725Z",
# "updated": "2020-12-12T01:48:13.725Z",
# "platform": "cool_sat1",
# "instruments": [
# "cool_sensor_v1"
# ],
# "constellation": "ion",
# "mission": "collection 5624",
# "gsd": 0.512
# },
# "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"
# },
# {
# "rel": "alternate",
# "type": "text/html",
# "href": "http://remotedata.io/catalog/20201211_223832_CS2/index.html",
# "title": "HTML version of this STAC Item"
# }
# ],
# "assets": {
# "analytic": {
# "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2_analytic.tif",
# "type": "image/tiff; application=geotiff; profile=cloud-optimized",
# "title": "4-Band Analytic",
# "roles": [
# "data"
# ]
# },
# "thumbnail": {
# "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.jpg",
# "title": "Thumbnail",
# "type": "image/png",
# "roles": [
# "thumbnail"
# ]
# },
# "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"
# ]
# },
# "udm": {
# "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2_analytic_udm.tif",
# "title": "Unusable Data Mask",
# "type": "image/tiff; application=geotiff;"
# },
# "json-metadata": {
# "href": "http://remotedata.io/catalog/20201211_223832_CS2/extended-metadata.json",
# "title": "Extended Metadata",
# "type": "application/json",
# "roles": [
# "metadata"
# ]
# },
# "ephemeris": {
# "href": "http://cool-sat.com/catalog/20201211_223832_CS2/20201211_223832_CS2.EPH",
# "title": "Satellite Ephemeris Metadata"
# }
# }
# }
# linter = Linter(file, assets=True)

# print(linter.valid_stac)

# print(linter.error_type)

# print(linter.error_msg)

# for k,v in linter.create_best_practices_dict().items():
# print(k,":",v)

# print(linter.schema)

# print(linter.file_name)
Loading

0 comments on commit 4a8c71d

Please sign in to comment.