Skip to content

Commit 88c07de

Browse files
Merge pull request #45 from sat-utils/develop
release 0.2
2 parents 8101782 + 64b977c commit 88c07de

File tree

19 files changed

+251
-304
lines changed

19 files changed

+251
-304
lines changed

.circleci/config.yml

Lines changed: 7 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25,55 +25,6 @@ references:
2525

2626
jobs:
2727

28-
build_and_test_35:
29-
docker:
30-
- image: circleci/python:3.5
31-
steps:
32-
- *restore_repo
33-
- checkout
34-
- *save_repo
35-
- restore_cache:
36-
keys:
37-
- v1-dependencies35-{{ checksum "requirements.txt"}}
38-
- v1-dependencies35
39-
- run: |
40-
pip install virtualenv
41-
virtualenv ~/venv35
42-
. ~/venv35/bin/activate
43-
pip install -r requirements.txt
44-
pip install -r requirements-dev.txt
45-
pip install .
46-
cd test
47-
pytest -v --cov satstac --cov-report term-missing
48-
- save_cache:
49-
key: v1-dependencies35-{{ checksum "requirements.txt"}}
50-
paths:
51-
- ~/venv35
52-
53-
build_and_test_36:
54-
docker:
55-
- image: circleci/python:3.6
56-
steps:
57-
- *restore_repo
58-
- checkout
59-
- *save_repo
60-
- restore_cache:
61-
keys:
62-
- v1-dependencies36-{{ checksum "requirements.txt"}}
63-
- v1-dependencies36
64-
- run: |
65-
python3 -m venv ~/venv36
66-
. ~/venv36/bin/activate
67-
pip install -r requirements.txt
68-
pip install -r requirements-dev.txt
69-
pip install .
70-
cd test
71-
pytest -v --cov satstac --cov-report term-missing
72-
- save_cache:
73-
key: v1-dependencies36-{{ checksum "requirements.txt"}}
74-
paths:
75-
- ~/venv36
76-
7728
build_and_test_37:
7829
docker:
7930
- image: circleci/python:3.7
@@ -101,17 +52,17 @@ jobs:
10152

10253
deploy:
10354
docker:
104-
- image: circleci/python:3.6
55+
- image: circleci/python:3.7
10556
steps:
10657
- *restore_repo
10758
- restore_cache:
10859
keys:
109-
- v1-dependencies36-{{ checksum "requirements.txt"}}
110-
- v1-dependencies36
60+
- v1-dependencies37-{{ checksum "requirements.txt"}}
61+
- v1-dependencies37
11162
- run:
11263
name: Deploy
11364
command: |
114-
. ~/venv36/bin/activate
65+
. ~/venv37/bin/activate
11566
mkdir -p ~/.ssh
11667
ssh-keyscan github.com >> ~/.ssh/known_hosts
11768
pip install twine
@@ -124,18 +75,12 @@ jobs:
12475
12576
workflows:
12677
version: 2
127-
build_test_35:
128-
jobs:
129-
- build_and_test_35
130-
build_test_36:
78+
build_test_37:
13179
jobs:
132-
- build_and_test_36
80+
- build_and_test_37
13381
- deploy:
13482
requires:
135-
- build_and_test_36
83+
- build_and_test_37
13684
filters:
13785
branches:
13886
only: master
139-
build_test_37:
140-
jobs:
141-
- build_and_test_37

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
66

77
## [Unreleased]
88

9+
### Changed
10+
- Thing.publish() removed. Self links are not used at all (and not recommended for static catalogs)
11+
- Thing.root() and Thing.parent() functions now return `None` if no root or parent (rather than an empty list). If more than one root or parent then an error will now be thrown.
12+
- Internal JSON data now stored in variable called `_data` rather than `data`
13+
914
## [v0.1.3] - 2019-05-04
1015

1116
### Added

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ The table below shows the corresponding versions between sat-stac and STAC:
4141
| sat-stac | STAC |
4242
| -------- | ---- |
4343
| 0.1.x | 0.6.x |
44+
| 0.2.x | 0.7.x |
4445

4546
## Tutorials
4647

satstac/catalog.py

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,25 @@ class Catalog(Thing):
1111
def __init__(self, data, root=None, **kwargs):
1212
""" Initialize a catalog with a catalog file """
1313
super(Catalog, self).__init__(data, **kwargs)
14-
self._root = root
1514

1615
@property
1716
def stac_version(self):
1817
""" Get the STAC version of this catalog """
19-
return self.data['stac_version']
18+
return self._data['stac_version']
2019

2120
@property
2221
def description(self):
2322
""" Get catalog description """
24-
return self.data.get('description', '')
23+
return self._data.get('description', '')
2524

2625
@classmethod
27-
def create(cls, id='stac-catalog', description='A STAC Catalog', root=None, **kwargs):
26+
def create(cls, id='stac-catalog', title='A STAC Catalog',
27+
description='A STAC Catalog', root=None, **kwargs):
2828
""" Create new catalog """
2929
kwargs.update({
3030
'id': id,
3131
'stac_version': STAC_VERSION,
32+
'title': title,
3233
'description': description,
3334
'links': []
3435
})
@@ -45,78 +46,49 @@ def catalogs(self):
4546
for cat in self.children():
4647
for subcat in cat.children():
4748
yield subcat
48-
# Python 2
49-
for x in subcat.catalogs():
50-
yield x
51-
# Python 3.3+
52-
# yield from subcat.catalogs()
49+
yield from subcat.catalogs()
5350
yield cat
5451

5552
def collections(self):
5653
""" Recursively get all collections within this Catalog """
5754
for cat in self.children():
58-
if 'extent' in cat.data.keys():
55+
if 'extent' in cat._data.keys():
5956
yield Collection.open(cat.filename)
6057
# TODO - keep going? if other Collections can appear below a Collection
6158
else:
62-
# Python 2
63-
for x in cat.collections():
64-
yield x
65-
# Python 3.3+
66-
# yield from cat.collections()
59+
yield from cat.collections()
6760

6861
def items(self):
6962
""" Recursively get all items within this Catalog """
7063
for item in self.links('item'):
7164
yield Item.open(item)
7265
for child in self.children():
73-
# Python 2
74-
for x in child.items():
75-
yield x
76-
# Python 3.3+
77-
# yield from child.items()
66+
yield from child.items()
7867

79-
def add_catalog(self, catalog):
68+
def add_catalog(self, catalog, basename='catalog'):
8069
""" Add a catalog to this catalog """
8170
if self.filename is None:
8271
raise STACError('Save catalog before adding sub-catalogs')
8372
# add new catalog child link
84-
child_link = '%s/catalog.json' % catalog.id
73+
child_link = '%s/%s.json' % (catalog.id, basename)
8574
child_fname = os.path.join(self.path, child_link)
8675
child_path = os.path.dirname(child_fname)
87-
root_link = self.links('root')[0]
76+
root_links = self.links('root')
77+
root_link = root_links[0] if len(root_links) > 0 else self.filename
8878
root_path = os.path.dirname(root_link)
8979
self.add_link('child', child_link)
9080
self.save()
9181
# strip self, parent, child links from catalog and add new links
9282
catalog.clean_hierarchy()
93-
catalog.add_link('self', os.path.join(self.endpoint(), os.path.relpath(child_fname, root_path)))
9483
catalog.add_link('root', os.path.relpath(root_link, child_path))
9584
catalog.add_link('parent', os.path.relpath(self.filename, child_path))
9685
# create catalog file
97-
catalog.save_as(child_fname)
86+
catalog.save(filename=child_fname)
9887
return self
9988

100-
def endpoint(self):
101-
""" Get endpoint URL to the root catalog """
102-
return os.path.dirname(self.root().links('self')[0])
103-
104-
def publish(self, endpoint, root=None):
105-
""" Update all self links throughout catalog to use new endpoint """
106-
# we don't use the catalogs and items functions as we'd have to go
107-
# through the tree twice, once for catalogs and once for items
108-
# update myself
109-
if root is None:
110-
root = self.filename
111-
super(Catalog, self).publish(endpoint, root=root)
112-
# update direct items
113-
for link in self.links('item'):
114-
item = Item.open(link)
115-
item.publish(endpoint, root=root)
116-
# follow children
117-
for cat in self.children():
118-
cat.publish(endpoint, root=root)
119-
89+
def add_collection(self, catalog, basename='collection'):
90+
""" Add a collection to this catalog """
91+
return self.add_catalog(catalog, basename=basename)
12092

12193

12294
# import and end of module prevents problems with circular dependencies.

satstac/cli.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,7 @@ def parse_args(args):
2828
parser.add_argument('id', help='ID of the new catalog')
2929
parser.add_argument('description', help='Description of new catalog')
3030
parser.add_argument('--filename', help='Filename of catalog', default='catalog.json')
31-
group = parser.add_argument_group('root catalog options (mutually exclusive)')
32-
group = group.add_mutually_exclusive_group(required=True)
33-
group.add_argument('--root', help='Filename to existing root catalog', default=None)
34-
group.add_argument('--endpoint', help='Endpoint for this new root catalog', default=None)
35-
36-
# command 2
37-
h = 'Update entire catalog with a new endpoint (update self links)'
38-
parser = subparsers.add_parser('publish', parents=[pparser], help=h, formatter_class=dhf)
39-
parser.add_argument('root', help='Filename to existing root catalog')
40-
parser.add_argument('endpoint', help='New endpoint')
41-
# parser.add_argument()
31+
parser.add_argument('--root', help='Filename to existing root catalog', default=None)
4232

4333
# turn Namespace into dictinary
4434
parsed_args = vars(parser0.parse_args(args))
@@ -57,11 +47,8 @@ def cli():
5747
cat = Catalog.create(id=args['id'], description=args['description'])
5848
root.add_catalog(cat)
5949
else:
60-
cat = Catalog.create(id=args['id'], description=args['description'], root=args['endpoint'])
61-
cat.save_as(args['filename'])
62-
elif cmd == 'publish':
63-
cat = Catalog.open(args['root'])
64-
cat.publish(args['endpoint'])
50+
cat = Catalog.create(id=args['id'], description=args['description'])
51+
cat.save(filename=args['filename'])
6552

6653

6754
if __name__ == "__main__":

satstac/collection.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,32 @@ def __init__(self, *args, **kwargs):
2222

2323
@property
2424
def title(self):
25-
return self.data.get('title', '')
25+
return self._data.get('title', '')
2626

2727
@property
2828
def keywords(self):
29-
return self.data.get('keywords', [])
29+
return self._data.get('keywords', [])
3030

3131
@property
3232
def version(self):
33-
return self.data.get('version', '')
33+
return self._data.get('version', '')
3434

3535
@property
3636
def license(self):
37-
return self.data.get('license')
37+
return self._data.get('license')
3838

3939
@property
4040
def providers(self):
41-
return self.data.get('providers', [])
41+
return self._data.get('providers', [])
4242

4343
@property
4444
def extent(self):
45-
return self.data.get('extent')
45+
return self._data.get('extent')
4646

4747
@property
4848
def properties(self):
4949
""" Get dictionary of properties """
50-
return self.data.get('properties', {})
50+
return self._data.get('properties', {})
5151

5252
@functools.lru_cache()
5353
def parent_catalog(self, path):
@@ -63,7 +63,7 @@ def parent_catalog(self, path):
6363
except STACError as err:
6464
# create a new sub-catalog
6565
subcat = self.create(id=d, description='%s catalog' % var_names[i])
66-
subcat.save_as(fname)
66+
subcat.save(filename=fname)
6767
# add the sub-catalog to this catalog
6868
cat.add_catalog(subcat)
6969
cat = subcat
@@ -88,13 +88,12 @@ def add_item(self, item, path='', filename='${id}'):
8888

8989
# create links from item
9090
item.clean_hierarchy()
91-
item.add_link('self', os.path.join(self.endpoint(), os.path.relpath(item_fname, root_path)))
9291
item.add_link('root', os.path.relpath(root_link, item_path))
9392
item.add_link('parent', os.path.relpath(parent.filename, item_path))
9493
# this assumes the item has been added to a Collection, not a Catalog
9594
item.add_link('collection', os.path.relpath(self.filename, item_path))
9695

9796
# save item
98-
item.save_as(item_fname)
97+
item.save(filename=item_fname)
9998
logger.debug('Added %s in %s seconds' % (item.filename, datetime.now()-start))
10099
return self

satstac/item.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def eobands(self):
4747
@property
4848
def properties(self):
4949
""" Get dictionary of properties """
50-
return self.data.get('properties', {})
50+
return self._data.get('properties', {})
5151

5252
def __getitem__(self, key):
5353
""" Get key from properties """
@@ -68,17 +68,17 @@ def datetime(self):
6868

6969
@property
7070
def geometry(self):
71-
return self.data['geometry']
71+
return self._data['geometry']
7272

7373
@property
7474
def bbox(self):
7575
""" Get bounding box of scene """
76-
return self.data['bbox']
76+
return self._data['bbox']
7777

7878
@property
7979
def assets(self):
8080
""" Return dictionary of assets """
81-
return self.data.get('assets', {})
81+
return self._data.get('assets', {})
8282

8383
@property
8484
def assets_by_common_name(self):
@@ -126,7 +126,7 @@ def substitute(self, string):
126126
def download_assets(self, keys=None, **kwargs):
127127
""" Download multiple assets """
128128
if keys is None:
129-
keys = self.data['assets'].keys()
129+
keys = self._data['assets'].keys()
130130
filenames = []
131131
for key in keys:
132132
filenames.append(self.download(key, **kwargs))

satstac/items.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ def save(self, filename):
109109

110110
def geojson(self):
111111
""" Get Items as GeoJSON FeatureCollection """
112-
features = [s.data for s in self._items]
112+
features = [s._data for s in self._items]
113113
geoj = {
114114
'type': 'FeatureCollection',
115115
'features': features,
116-
'collections': [c.data for c in self._collections],
116+
'collections': [c._data for c in self._collections],
117117
}
118118
if self._search is not None:
119119
geoj['search'] = self._search

0 commit comments

Comments
 (0)