Skip to content

Commit ec3ece3

Browse files
authored
Merge pull request #169 from open-craft/artur/aws-region
feat: support for specifying AWS region
2 parents e0ef850 + f375506 commit ec3ece3

4 files changed

Lines changed: 52 additions & 6 deletions

File tree

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ Change Log
1414
Unreleased
1515
**********
1616

17+
3.5.0
18+
*****
19+
20+
Added
21+
=====
22+
23+
* feat: support for specifying AWS region
24+
1725
3.4.1
1826
*****
1927

djpyfs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# pylint: disable=django-not-configured
22
"""init file"""
3-
__version__ = '3.4.1'
3+
__version__ = '3.5.0'

djpyfs/djpyfs.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,16 @@ def get_s3fs(namespace):
126126
"""
127127
key_id = DJFS_SETTINGS.get('aws_access_key_id', None)
128128
key_secret = DJFS_SETTINGS.get('aws_secret_access_key', None)
129+
region = DJFS_SETTINGS.get('region', None)
129130

130131
fullpath = namespace
131132

132133
if 'prefix' in DJFS_SETTINGS:
133134
fullpath = os.path.join(DJFS_SETTINGS['prefix'], fullpath)
134135

135-
s3fs = S3FS(DJFS_SETTINGS['bucket'], fullpath, aws_access_key_id=key_id, aws_secret_access_key=key_secret)
136+
s3fs = S3FS(DJFS_SETTINGS['bucket'], fullpath,
137+
aws_access_key_id=key_id, aws_secret_access_key=key_secret,
138+
region=region)
136139

137140
def get_s3_url(self, filename, timeout=60): # pylint: disable=unused-argument
138141
"""
@@ -154,7 +157,9 @@ def get_s3_url(self, filename, timeout=60): # pylint: disable=unused-argument
154157

155158
try:
156159
if not S3CONN:
157-
S3CONN = boto3.client('s3', aws_access_key_id=key_id, aws_secret_access_key=key_secret)
160+
S3CONN = boto3.client('s3', aws_access_key_id=key_id,
161+
aws_secret_access_key=key_secret,
162+
region_name=region)
158163

159164
return S3CONN.generate_presigned_url(
160165
"get_object",
@@ -168,7 +173,9 @@ def get_s3_url(self, filename, timeout=60): # pylint: disable=unused-argument
168173
except Exception: # pylint: disable=broad-except
169174
# Retry on error; typically, if the connection has timed out, but
170175
# the broad except covers all errors.
171-
S3CONN = boto3.client('s3', aws_access_key_id=key_id, aws_secret_access_key=key_secret)
176+
S3CONN = boto3.client('s3', aws_access_key_id=key_id,
177+
aws_secret_access_key=key_secret,
178+
region_name=region)
172179

173180
return S3CONN.generate_presigned_url(
174181
"get_object",

djpyfs/tests.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ def setUp(self):
312312
def _setUpS3(self):
313313
"""setup class"""
314314

315+
djpyfs.S3CONN = None
316+
315317
# Start mocking S3
316318
self.mock_s3 = mock_s3()
317319
self.mock_s3.start()
@@ -320,19 +322,23 @@ def _setUpS3(self):
320322
self.conn = boto3.resource('s3')
321323
self.conn.create_bucket(Bucket=djpyfs.DJFS_SETTINGS['bucket'])
322324

323-
def test_aws_credentials(self):
325+
def test_aws_options(self):
324326
fs = djpyfs.get_filesystem(self.namespace)
325327
self.assertEqual(fs.aws_access_key_id, 'foo')
326328
self.assertEqual(fs.aws_secret_access_key, 'bar')
329+
self.assertEqual(fs.region, djpyfs.DJFS_SETTINGS.get('region', None))
327330

328331
# This test is only relevant for S3. Generate some fake errors to make
329332
# sure we cover the retry code.
330333
def test_get_url_retry(self):
334+
fs = djpyfs.get_filesystem(self.namespace)
335+
# Call get_url() once to initialise global S3CONN so we can patch its
336+
# generate_presigned_url() method below.
337+
fs.get_url(self.relative_path_to_test_file)
331338
with patch('boto3.client') as mock_client:
332339
mock_client.side_effect = AttributeError("Some attribute error occurred")
333340
with patch.object(djpyfs.S3CONN, "generate_presigned_url") as mock_client:
334341
mock_client.side_effect = AttributeError("Some attribute error occurred")
335-
fs = djpyfs.get_filesystem(self.namespace)
336342
with self.assertRaises(AttributeError):
337343
fs.get_url(self.relative_path_to_test_file).startswith(self.expected_url_prefix)
338344

@@ -364,3 +370,28 @@ def setUp(self):
364370
f"{djpyfs.DJFS_SETTINGS['prefix']}/{self.namespace}/"
365371
f"{self.relative_path_to_test_file}")
366372
self._setUpS3()
373+
374+
375+
# pylint: disable=test-inherits-tests
376+
class S3TestRegion(S3Test):
377+
"""
378+
Same as S3Test above, but specifies AWS region.
379+
"""
380+
381+
djfs_settings = {
382+
'type': 's3fs',
383+
'directory_root': 'django-pyfs/static/django-pyfs-test',
384+
'url_root': '/static/django-pyfs-test',
385+
'aws_access_key_id': 'foo',
386+
'aws_secret_access_key': 'bar',
387+
'bucket': 'test_bucket',
388+
'region': 'me-south-1'
389+
}
390+
391+
def setUp(self):
392+
super().setUp()
393+
394+
self.expected_url_prefix = (f"https://s3.{djpyfs.DJFS_SETTINGS['region']}.amazonaws.com/"
395+
f"{djpyfs.DJFS_SETTINGS['bucket']}/{self.namespace}/"
396+
f"{self.relative_path_to_test_file}")
397+
self._setUpS3()

0 commit comments

Comments
 (0)