Skip to content

Commit

Permalink
Merge pull request #60 from sat-utils/develop
Browse files Browse the repository at this point in the history
publish 0.4.0-rc2
  • Loading branch information
matthewhanson authored Jun 12, 2020
2 parents d28502f + 1cb3617 commit d6d4866
Show file tree
Hide file tree
Showing 22 changed files with 765 additions and 877 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

[![CircleCI](https://circleci.com/gh/sat-utils/sat-stac.svg?style=svg&circle-token=ef97f3eea6cf901646fc2951e5a941686456b0da)](https://circleci.com/gh/sat-utils/sat-stac) [![PyPI version](https://badge.fury.io/py/sat-stac.svg)](https://badge.fury.io/py/sat-stac) [![codecov](https://codecov.io/gh/sat-utils/sat-stac/branch/master/graph/badge.svg)](https://codecov.io/gh/sat-utils/sat-stac)

This is a Python 3 library for working with [Spatio-Temporal Asset Catalogs (STAC)](https://github.com/radiantearth/stac-spec). It can be used to
This is a Python 3 library for reading and working with existing [Spatio-Temporal Asset Catalogs (STAC)](https://github.com/radiantearth/stac-spec). It can be used to

- Open and traverse STAC catalogs
- Download assets from STAC Items, using templated path names
- Save and load [Self-contained STAC catalogs](https://github.com/radiantearth/stac-spec/tree/v0.9.0-rc1/extensions/single-file-stac)
- Create and update catalogs*
- Add or remove a STAC Collections of Items from a catalog*

* sat-stac works for small catalogs or a small rate of updates. It is more useful for reading existing catalogs (either static or dynamic). For creating or large updating of catalogs, [PySTAC](https://github.com/azavea/pystac) is the better alternative.
The features for creating and updating existing catalogs in past versions have been removed in 0.4.0. If writing catalogs is needed, see [PySTAC](https://github.com/azavea/pystac).

## Installation

Expand Down Expand Up @@ -44,6 +42,7 @@ The table below shows the corresponding versions between sat-stac and STAC:
| 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.9.x |
| 0.4.x | 0.6.x - 1.0.0-beta.1 |

## Tutorials

Expand Down
3 changes: 2 additions & 1 deletion satstac/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from .version import __version__
from .thing import Thing, STACError
from .config import STAC_VERSION

STAC_VERSION = os.getenv('STAC_VERSION', '1.0.0-beta.1')


class Catalog(Thing):
Expand Down
17 changes: 9 additions & 8 deletions satstac/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ def extent(self):
return self._data.get('extent')

@property
def properties(self):
""" Get dictionary of properties """
return self._data.get('properties', {})
def summaries(self):
""" Get dictionary of summaries """
return self._data.get('summaries', {})

@functools.lru_cache()
def parent_catalog(self, item, path_template):
""" Given relative filename to a new Item find parent catalog """
cat = self
path = item.get_path(path_template)
path = item.get_path(os.path.dirname(path_template))
var_names = [v.strip('$').strip('{}') for v in utils.splitall(path_template)]
for i, d in enumerate(utils.splitall(path)):
fname = os.path.join(os.path.join(cat.path, d), 'catalog.json')
Expand All @@ -69,18 +69,17 @@ def parent_catalog(self, item, path_template):
cat = subcat
return cat.filename

def add_item(self, item, path_template='', filename_template='${id}.json'):
def add_item(self, item, filename_template='${id}.json'):
""" Add an item to this collection """
start = datetime.now()
if self.filename is None:
raise STACError('Save catalog before adding items')
item_link = os.path.join(item.get_path(os.path.join(path_template, filename_template)))
item_link = os.path.join(item.get_path(os.path.join(filename_template)))
item_fname = os.path.join(self.path, item_link)
item_path = os.path.dirname(item_fname)
root_link = self.links('root')[0]
#root_path = os.path.dirname(root_link)

parent = Catalog.open(self.parent_catalog(item, path_template))
parent = Catalog.open(self.parent_catalog(item, filename_template))

# create link to item
parent.add_link('item', os.path.relpath(item_fname, parent.path))
Expand All @@ -94,6 +93,8 @@ def add_item(self, item, path_template='', filename_template='${id}.json'):
item.add_link('collection', os.path.relpath(self.filename, item_path))

# save item

item.save(filename=item_fname)
logger.debug('Added %s in %s seconds' % (item.filename, datetime.now()-start))

return self
5 changes: 0 additions & 5 deletions satstac/config.py

This file was deleted.

23 changes: 8 additions & 15 deletions satstac/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from dateutil.parser import parse as dateparse

from satstac import __version__, STACError, Thing, utils
from .config import STAC_PATH_TEMPLATE

logger = logging.getLogger(__name__)

FILENAME_TEMPLATE = os.getenv('SATSEARCH_FILENAME_TEMPLATE', '${collection}/${date}/${id}')


class Item(Thing):

Expand All @@ -35,15 +36,6 @@ def collection(self):
self._collection = Collection.open(link[0])
return self._collection

@property
def eobands(self):
""" Get eo:bands from Item or from Collection """
if 'eo:bands' in self.properties:
return self.properties['eo:bands']
elif self.collection() is not None and 'eo:bands' in self.collection().properties:
return self.collection()['eo:bands']
return []

@property
def properties(self):
""" Get dictionary of properties """
Expand Down Expand Up @@ -83,12 +75,12 @@ def assets(self):
@property
def assets_by_common_name(self):
""" Get assets by common band name (only works for assets containing 1 band """
if self._assets_by_common_name is None and len(self.eobands) > 0:
if self._assets_by_common_name is None:
self._assets_by_common_name = {}
for a in self.assets:
bands = self.assets[a].get('eo:bands', [])
if len(bands) == 1:
eo_band = self.eobands[bands[0]].get('common_name')
eo_band = bands[0].get('common_name')
if eo_band:
self._assets_by_common_name[eo_band] = self.assets[a]
return self._assets_by_common_name
Expand All @@ -108,7 +100,8 @@ def get_path(self, template):
subs = {}
for key in [i[1] for i in Formatter().parse(_template.rstrip('/')) if i[1] is not None]:
if key == 'collection':
subs[key] = self._data['collection']
# make this compatible with older versions of stac where collection is in properties
subs[key] = self._data.get('collection', self['collection'])
elif key == 'id':
subs[key] = self.id
elif key in ['date', 'year', 'month', 'day']:
Expand All @@ -127,14 +120,14 @@ def download_assets(self, keys=None, **kwargs):
filenames.append(self.download(key, **kwargs))
return filenames

def download(self, key, overwrite=False, path_template=STAC_PATH_TEMPLATE, requester_pays=False):
def download(self, key, overwrite=False, filename_template=FILENAME_TEMPLATE, requester_pays=False):
""" Download this key (e.g., a band, or metadata file) from the scene """
asset = self.asset(key)
if asset is None:
return None

ext = os.path.splitext(asset['href'])[1]
filename = self.get_path(path_template) + '_' + key + ext
filename = self.get_path(filename_template) + '_' + key + ext
if not os.path.exists(filename) or overwrite:
try:
utils.download_file(asset['href'], filename=filename, requester_pays=requester_pays)
Expand Down
5 changes: 3 additions & 2 deletions satstac/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import base64
import calendar
import collections
import datetime
import hashlib
import hmac
Expand All @@ -10,6 +9,8 @@
import sys
import time

from collections.abc import Mapping

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -44,7 +45,7 @@ def dict_merge(dct, merge_dct, add_keys=True):

for k, v in merge_dct.items():
if (k in dct and isinstance(dct[k], dict)
and isinstance(merge_dct[k], collections.Mapping)):
and isinstance(merge_dct[k], Mapping)):
dct[k] = dict_merge(dct[k], merge_dct[k], add_keys=add_keys)
else:
dct[k] = merge_dct[k]
Expand Down
2 changes: 1 addition & 1 deletion satstac/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.4.0-rc1'
__version__ = '0.4.0-rc2'
2 changes: 1 addition & 1 deletion test/catalog/catalog.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id": "stac", "description": "A STAC of public datasets", "stac_version": "0.6.0", "links": [{"rel": "self", "href": "catalog.json"}, {"rel": "root", "href": "catalog.json"}, {"rel": "child", "href": "eo/catalog.json"}]}
{"id": "stac-catalog", "description": "An example STAC catalog", "stac_version": "1.0.0-beta.1", "links": [{"rel": "self", "href": "catalog.json"}, {"rel": "root", "href": "catalog.json"}, {"rel": "child", "href": "eo/catalog.json"}]}
6 changes: 3 additions & 3 deletions test/catalog/eo/catalog.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "stac-eo",
"description": "A STAC of EO Data",
"stac_version": "0.6.0",
"id": "stac-catalog-eo",
"description": "An example STAC sub-catalog of EO Data",
"stac_version": "1.0.0-beta.1",
"links": [
{
"rel": "self",
Expand Down
Loading

0 comments on commit d6d4866

Please sign in to comment.