diff --git a/CHANGELOG.md b/CHANGELOG.md index bafbfbe..4ba6f5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [v0.3.1] - 2019-12-06 + +### Fixed +- Item constructor now properly accepts passing in the collection +- Item.substitute and item.get_filename now properly accept ${collection} as a template parameter + +### Deprecated +- ItemCollection.load() is now ItemCollection.open() and behaves like Item.open() (able to read remote files) + ## [v0.3.0] - 2019-09-19 ### Fixed @@ -56,7 +65,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. Initial Release [Unreleased]: https://github.com/sat-utils/sat-stac/compare/master...develop -[v0.2.1]: https://github.com/sat-utils/sat-stac/compare/0.2.0...v0.3.0 +[v0.3.0]: https://github.com/sat-utils/sat-stac/compare/0.2.0...v0.3.0 [v0.2.0]: https://github.com/sat-utils/sat-stac/compare/0.1.3...v0.2.0 [v0.1.3]: https://github.com/sat-utils/sat-stac/compare/0.1.2...v0.1.3 [v0.1.2]: https://github.com/sat-utils/sat-stac/compare/0.1.1...v0.1.2 diff --git a/README.md b/README.md index 3cb6e33..0ee64a9 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,13 @@ The table below shows the corresponding versions between sat-stac and STAC: | sat-stac | STAC | | -------- | ---- | -| 0.1.x | 0.6.x, 0.7.x | -| 0.2.x | 0.6.x, 0.7.x | -| 0.3.x | 0.8.x | +| 0.1.x | 0.6.x - 0.7.x | +| 0.2.x | 0.6.x - 0.7.x | +| 0.3.x | 0.6.x - 0.8.x | ## Tutorials There are two tutorials. [Tutorial-1](tutorial-1.ipynb) includes an overview of how to create and manipulate STAC static catalogs. [Tutorial-2](tutorial-2.ipynb) is on the Python classes that reflect STAC entities: Catalogs, Collections, and Items. ## About -[sat-stac](https://github.com/sat-utils/sat-stac) was created by [Development Seed]() and is part of a collection of tools called [sat-utils](https://github.com/sat-utils). +[sat-stac](https://github.com/sat-utils/sat-stac) is part of a collection of tools called [sat-utils](https://github.com/sat-utils). diff --git a/satstac/item.py b/satstac/item.py index cbd7094..44ded20 100644 --- a/satstac/item.py +++ b/satstac/item.py @@ -114,7 +114,9 @@ def substitute(self, string): string = string.replace(':', '_colon_') subs = {} for key in [i[1] for i in Formatter().parse(string.rstrip('/')) if i[1] is not None]: - if key == 'id': + if key == 'collection': + subs[key] = self._data['collection'] + elif key == 'id': subs[key] = self.id elif key in ['date', 'year', 'month', 'day']: vals = {'date': self.date, 'year': self.date.year, 'month': self.date.month, 'day': self.date.day} diff --git a/satstac/itemcollection.py b/satstac/itemcollection.py index 500f545..19e7573 100644 --- a/satstac/itemcollection.py +++ b/satstac/itemcollection.py @@ -1,8 +1,14 @@ import json +import os.path as op +import requests +from logging import getLogger from .collection import Collection from .item import Item -from .utils import terminal_calendar +from .thing import STACError +from .utils import terminal_calendar, get_s3_signed_url + +logger = getLogger(__name__) class ItemCollection(object): @@ -23,13 +29,42 @@ def __init__(self, items, collections=[], search={}): i._collection = cols[col] @classmethod - def load(cls, filename): + def open_remote(self, url, headers={}): + """ Open remote file """ + resp = requests.get(url, headers=headers) + if resp.status_code == 200: + dat = resp.text + else: + raise STACError('Unable to open %s' % url) + return json.loads(dat) + + @classmethod + def open(cls, filename): + """ Load an Items class from a GeoJSON FeatureCollection """ + """ Open an existing JSON data file """ + logger.debug('Opening %s' % filename) + if filename[0:5] == 'https': + try: + data = cls.open_remote(filename) + except STACError as err: + # try signed URL + url, headers = get_s3_signed_url(filename) + data = cls.open_remote(url, headers) + else: + if op.exists(filename): + data = open(filename).read() + data = json.loads(data) + else: + raise STACError('%s does not exist locally' % filename) + collections = [Collection(col) for col in data['collections']] + items = [Item(feature) for feature in data['features']] + return cls(items, collections=collections, search=data.get('search')) + + @classmethod + def load(cls, *args, **kwargs): """ Load an Items class from a GeoJSON FeatureCollection """ - with open(filename) as f: - geoj = json.loads(f.read()) - collections = [Collection(col) for col in geoj['collections']] - items = [Item(feature) for feature in geoj['features']] - return cls(items, collections=collections, search=geoj.get('search')) + logger.warning(f"ItemCollection.load() is deprecated, use ItemCollection.open()") + return cls.open(*args, **kwargs) def __len__(self): """ Number of scenes """ diff --git a/satstac/version.py b/satstac/version.py index 0404d81..e1424ed 100644 --- a/satstac/version.py +++ b/satstac/version.py @@ -1 +1 @@ -__version__ = '0.3.0' +__version__ = '0.3.1'