Skip to content

Commit 1a8a55b

Browse files
Merge pull request #32 from sat-utils/develop
release 0.1.2
2 parents 4135bf8 + 0f4e5ce commit 1a8a55b

File tree

8 files changed

+60
-13
lines changed

8 files changed

+60
-13
lines changed

CHANGELOG.md

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

77
## [Unreleased]
88

9+
## [v0.1.2] - 2019-02-14
10+
11+
### Added
12+
- Item.download_assets() and Items.download_assets() works as download() except accepts a list of keys rather than a single key. Passing in `None` for keys will download all assets.
13+
- requestor_pays keyword option added to Item.download() (and Items.download()). Defaults to False. Use it to acknowledge paying egress costs when downloading data from a Reqeuestor Pays bucket (e.g., Sentinel-2). If the bucket is requestor pays and this is not set to True an AccessDenied error message will occur.
14+
915
## [v0.1.1] - 2019-01-15
1016

1117
### Added
@@ -15,7 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1521
### Changed
1622

1723
- Python 3 only. With Python 2.7 going unsupported in 2020 the time has come to stop supporting 2.7. There are too many additions in Python3 that continue to make backward compatability with Python 2.7 more difficult. In the case of this release the addition of caching using `functools` made sat-stac incompatible with Python 2.7.
18-
- More lenient version requirements for `requests` (now <=2.19.1). Otherwise can cause dependency incompatibility problems in some cases.
24+
- More lenient version requirements for `requests` (now >=2.19.1). Otherwise can cause dependency incompatibility problems in some cases.
1925
- Behavior of `path` and `filename` keyword arguments to Collection.add_item() has changed slightly. The components of `path` are now exclusively used to generate sub-catalogs, while `filename` is the relative filename (which could include a further subdirectory) from the last sub-catalog (it's parent). Before, it was assumed that Item files were always in a single subdirectory under it's parent catalog.
2026
- Tutorials updated
2127

@@ -24,5 +30,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2430
Initial Release
2531

2632
[Unreleased]: https://github.com/sat-utils/sat-stac/compare/master...develop
27-
[v0.1.1]: https://github.com/sat-utils/sat-api/compare/0.1.0...v0.1.1
28-
[v0.1.0]: https://github.com/sat-utils/sat-stac/tree/0.1.0
33+
[v0.1.2]: https://github.com/sat-utils/sat-stac/compare/0.1.1...v0.1.2
34+
[v0.1.1]: https://github.com/sat-utils/sat-stac/compare/0.1.0...v0.1.1
35+
[v0.1.0]: https://github.com/sat-utils/sat-stac/tree/0.1.0

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ $ pip install .
3333
The latest version of sat-stac is 0.1.1, which uses the STAC spec v0.6.0. To install other versions of sat-stac, install the matching version of sat-stac.
3434

3535
```bash
36-
pip install satstac==0.1.0
36+
pip install sat-stac==0.1.0
3737
```
3838

3939
The table below shows the corresponding versions between sat-stac and STAC:

satstac/item.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,16 @@ def substitute(self, string):
123123
subs[key] = self[key.replace('_colon_', ':')]
124124
return Template(string).substitute(**subs)
125125

126-
def download(self, key, overwrite=False, path='', filename='${id}'):
126+
def download_assets(self, keys=None, **kwargs):
127+
""" Download multiple assets """
128+
if keys is None:
129+
keys = self.data['assets'].keys()
130+
filenames = []
131+
for key in keys:
132+
filenames.append(self.download(key, **kwargs))
133+
return filenames
134+
135+
def download(self, key, overwrite=False, path='', filename='${id}', requestor_pays=False):
127136
""" Download this key (e.g., a band, or metadata file) from the scene """
128137
asset = self.asset(key)
129138
if asset is None:
@@ -137,7 +146,7 @@ def download(self, key, overwrite=False, path='', filename='${id}'):
137146
ext = os.path.splitext(asset['href'])[1]
138147
fout = os.path.join(_path, fname + '_' + key + ext)
139148
if not os.path.exists(fout) or overwrite:
140-
_filename = utils.download_file(asset['href'], filename=fout)
149+
_filename = utils.download_file(asset['href'], filename=fout, requestor_pays=requestor_pays)
141150
else:
142151
_filename = fout
143152
except Exception as e:

satstac/items.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ def filter(self, key, values):
118118
items += list(filter(lambda x: x[key] == val, self._items))
119119
self._items = items
120120

121+
def download_assets(self, *args, **kwargs):
122+
filenames = []
123+
for i in self._items:
124+
fnames = i.download_assets(*args, **kwargs)
125+
if len(fnames) > 0:
126+
filenames.append(fnames)
127+
return filenames
128+
121129
def download(self, *args, **kwargs):
122130
""" Download all Items """
123131
dls = []

satstac/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@ def dict_merge(dct, merge_dct, add_keys=True):
5252
return dct
5353

5454

55-
def download_file(url, filename=None):
55+
def download_file(url, filename=None, requestor_pays=False):
5656
""" Download a file as filename """
5757
filename = os.path.basename(url) if filename is None else filename
5858
logger.info('Downloading %s as %s' % (url, filename))
5959
headers = {}
6060
# check if on s3, if so try to sign it
6161
if 's3.amazonaws.com' in url:
62-
signed_url, signed_headers = get_s3_signed_url(url)
62+
signed_url, signed_headers = get_s3_signed_url(url, requestor_pays=requestor_pays)
6363
resp = requests.get(signed_url, headers=signed_headers, stream=True)
6464
if resp.status_code != 200:
6565
resp = requests.get(url, headers=headers, stream=True)

satstac/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.1.1'
1+
__version__ = '0.1.2'

test/test_item.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ def test_download(self):
9797
fname = item.download(key='MTL', path=self.path)
9898
assert(os.path.exists(fname))
9999

100+
def test_download_assets(self):
101+
""" Retrieve multiple data files """
102+
item = Item.open(self.filename)
103+
fnames = item.download_assets(keys=['MTL', 'ANG'], path=self.path)
104+
for f in fnames:
105+
assert(os.path.exists(f))
106+
100107
def test_download_nonexist(self):
101108
""" Test downloading of non-existent file """
102109
item = Item.open(self.filename)

test/test_items.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,21 @@
22
import unittest
33

44
from satstac import Items, Item
5+
from shutil import rmtree
56

67
testpath = os.path.dirname(__file__)
78

89

910
class Test(unittest.TestCase):
1011

12+
path = os.path.join(testpath, 'test-item')
13+
14+
@classmethod
15+
def tearDownClass(cls):
16+
""" Remove test files """
17+
if os.path.exists(cls.path):
18+
rmtree(cls.path)
19+
1120
def load_items(self):
1221
return Items.load(os.path.join(testpath, 'items.json'))
1322

@@ -89,14 +98,21 @@ def test_filter(self):
8998
items.filter('eo:cloud_cover', [100])
9099
assert(len(items) == 1)
91100

101+
def test_download_assets(self):
102+
""" Download multiple assets from all items """
103+
items = self.load_items()
104+
filenames = items.download_assets(keys=['MTL', 'ANG'], path=self.path)
105+
assert(len(filenames) == 2)
106+
for fnames in filenames:
107+
assert(len(fnames) == 2)
108+
for f in fnames:
109+
assert(os.path.exists(f))
110+
92111
def test_download(self):
93112
""" Download a data file from all items """
94113
items = self.load_items()
95114

96-
fnames = items.download(key='MTL')
115+
fnames = items.download(key='MTL', path=self.path)
97116
assert(len(fnames) == 2)
98117
for f in fnames:
99118
assert(os.path.exists(f))
100-
os.remove(f)
101-
assert(not os.path.exists(f))
102-
#shutil.rmtree(os.path.join(testpath, 'landsat-8-l1'))

0 commit comments

Comments
 (0)