Skip to content

Commit

Permalink
fix s3.find function and add test
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewhanson committed Oct 8, 2019
1 parent 0fb9304 commit a6f10da
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 24 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [v0.0.1] - 2019-10-08
## [v0.0.2] - 2019-10-08

Initial Release

[Unreleased]: https://github.com/matthewhanson/boto3-utils/compare/master...develop
[v0.0.1]: https://github.com/matthewhanson/boto3-utils/tree/0.1.0
[v0.0.2]: https://github.com/matthewhanson/boto3-utils/tree/0.0.2
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include requirements.txt
include requirements-dev.txt
8 changes: 4 additions & 4 deletions boto3utils/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def upload(filename, uri, public=False, extra={}):
s3_uri = urlparse(uri)
uri_out = 's3://%s' % op.join(s3_uri['bucket'], s3_uri['key'])
if public:
extra['acl'] = 'public-read'
extra['ACL'] = 'public-read'
with open(filename, 'rb') as data:
s3.upload_fileobj(data, s3_uri['bucket'], s3_uri['key'], ExtraArgs=extra)
return uri_out
Expand Down Expand Up @@ -108,8 +108,8 @@ def find(url, suffix=''):

# If the prefix is a single string (not a tuple of strings), we can
# do the filtering directly in the S3 API.
if isinstance(parts['prefix'], str):
kwargs['Prefix'] = parts['prefix']
if isinstance(parts['key'], str):
kwargs['Prefix'] = parts['key']

while True:
# The S3 API response is a large blob of metadata.
Expand All @@ -122,7 +122,7 @@ def find(url, suffix=''):

for obj in contents:
key = obj['Key']
if key.startswith(parts['prefix']) and key.endswith(suffix):
if key.startswith(parts['key']) and key.endswith(suffix):
yield obj['Key']

# The S3 API is paginated, returning up to 1000 keys at a time.
Expand Down
2 changes: 1 addition & 1 deletion boto3utils/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.1'
__version__ = '0.0.2'
43 changes: 26 additions & 17 deletions test/test_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
import os
import pytest

# this must be imported before any boto3 module
from moto import mock_s3
from boto3utils import s3 as s3utils

from boto3utils import s3
from shutil import rmtree


BUCKET = 'testbucket'
KEY = 'testkey'


@pytest.fixture(scope='function')
def s3():
def s3mock():
with mock_s3():
client = boto3.client('s3', region_name='us-west-2',
aws_access_key_id='noid', aws_secret_access_key='nokey')
Expand All @@ -25,47 +28,53 @@ def s3():


def test_urlparse():
parts = s3utils.urlparse('s3://bucket/path')
parts = s3.urlparse('s3://bucket/path')
assert(parts['bucket'] == 'bucket')
assert(parts['key'] == 'path')
assert(parts['key'] == parts['filename'])

def test_urlparse_nokey():
parts = s3utils.urlparse('s3://bucket')
parts = s3.urlparse('s3://bucket')
assert(parts['bucket'] == 'bucket')
assert(parts['key'] == '')
assert(parts['filename'] == '')

def test_urlparse_invalid():
with pytest.raises(Exception):
s3utils.urlparse('invalid')
s3.urlparse('invalid')

def test_s3_to_https():
s3url = 's3://bucket/prefix/filename'
url = s3utils.s3_to_https(s3url, region='us-west-2')
url = s3.s3_to_https(s3url, region='us-west-2')
assert(url == 'https://bucket.s3.us-west-2.amazonaws.com/prefix/filename')

def test_exists(s3):
exists = s3utils.exists('s3://%s/%s' % (BUCKET, 'keymaster'))
def test_exists(s3mock):
exists = s3.exists('s3://%s/%s' % (BUCKET, 'keymaster'))
assert(exists is False)
exists = s3utils.exists('s3://%s/%s' % (BUCKET, KEY))
exists = s3.exists('s3://%s/%s' % (BUCKET, KEY))
assert(exists)

def test_exists_invalid():
with pytest.raises(Exception):
s3utils.exists('invalid')
s3.exists('invalid')

def test_upload_download(s3):
def test_upload_download(s3mock):
url = 's3://%s/mytestfile' % BUCKET
s3utils.upload(__file__, url)
exists = s3utils.exists(url)
s3.upload(__file__, url, public=True)
exists = s3.exists(url)
assert(exists)
path = os.path.join(testpath, 'test_s3/test_upload_download')
fname = s3utils.download(url, path)
fname = s3.download(url, path)
assert(os.path.exists(fname))
assert(os.path.join(path, os.path.basename(url)) == fname)
rmtree(path)

def test_read_json(s3):
def test_read_json(s3mock):
url = 's3://%s/test.json' % BUCKET
out = s3utils.read_json(url)
assert(out['field'] == 'value')
out = s3.read_json(url)
assert(out['field'] == 'value')

def test_find(s3mock):
urls = list(s3.find('s3://%s/test' % BUCKET))
assert(len(urls) > 0)
assert('test.json' in urls)

0 comments on commit a6f10da

Please sign in to comment.