Skip to content

Commit

Permalink
Handling optional dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
bsipocz committed Sep 25, 2023
1 parent 1bcc76f commit 5b8f6a4
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
37 changes: 27 additions & 10 deletions pyvo/utils/tests/test_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,24 @@
import requests_mock
from contextlib import contextmanager
import urllib
import boto3
from botocore.exceptions import ClientError
from moto import mock_s3


from astropy.utils.data import get_pkg_data_contents

from pyvo.utils.download import (_filename_from_url, PyvoUserWarning, _s3_is_accessible,
http_download, aws_download)

## Useful variables
try:
# Both boto3, botocore and moto are optional dependencies, but the former 2 are
# dependencies of the latter, so it's enough to handle them with one variable
import boto3
from botocore.exceptions import ClientError
from moto import mock_s3
HAS_MOTO = True
except ImportError:
HAS_MOTO = False


# Useful variables
# For http_download:
get_pkg_data_contents = partial(
get_pkg_data_contents, package=__package__, encoding='binary')
Expand Down Expand Up @@ -60,7 +67,7 @@ def test__filename_from_url():
'https://example.com/files/myfile.pdf',
'http://somesite.com/service?file=/location/myfile.pdf&size=large'
]

for url in urls:
filename = _filename_from_url(url)
assert(filename == 'myfile.pdf')
Expand All @@ -79,19 +86,19 @@ def callback(request, context):


def test_http_download__noPath(http_mock):
filename = http_download('http://example.com/data/basic.xml',
filename = http_download('http://example.com/data/basic.xml',
local_filepath=None, cache=False)
assert(filename == 'basic.xml')
os.remove('basic.xml')


def test_http_download__noFile(http_mock):
with pytest.raises(urllib.error.URLError):
filename = http_download('http://example.com/data/nofile.fits')


def test_http_download__wPath(http_mock):
filename = http_download('http://example.com/data/basic.xml',
filename = http_download('http://example.com/data/basic.xml',
local_filepath='basic2.xml', cache=False)
assert(filename == 'basic2.xml')
assert(os.path.exists('basic2.xml'))
Expand All @@ -104,12 +111,14 @@ def test_http_download__wrong_cache(http_mock):
fp.write('some content')
# get it from cache
with pytest.warns(PyvoUserWarning):
filename = http_download('http://example.com/data/basic.xml',
filename = http_download('http://example.com/data/basic.xml',
local_filepath='basic.xml', cache=True)
assert(os.path.getsize('basic.xml') == 901)
os.remove('basic.xml')



@pytest.mark.skipif('not HAS_MOTO')
@pytest.fixture(name='s3_mock')
def _s3_mock(mocker):
with mock_s3():
Expand All @@ -120,25 +129,29 @@ def _s3_mock(mocker):
yield conn


@pytest.mark.skipif('not HAS_MOTO')
def test_s3_mock_basic(s3_mock):
s3 = s3_mock.meta.client
body = s3_mock.Object(s3_bucket, s3_key).get()['Body']
content = body.read().decode('utf-8')
assert content == 'my content'


@pytest.mark.skipif('not HAS_MOTO')
def test__s3_is_accessible_yes(s3_mock):
accessible, exc = _s3_is_accessible(s3_mock, s3_bucket, s3_key)
assert(accessible)
assert(exc is None)


@pytest.mark.skipif('not HAS_MOTO')
def test__s3_is_accessible_no_bucket(s3_mock):
accessible, exc = _s3_is_accessible(s3_mock, 'some-bucket', s3_key)
assert(not accessible)
assert('NoSuchBucket' in str(exc))


@pytest.mark.skipif('not HAS_MOTO')
def test__s3_is_accessible_no_key(s3_mock):
accessible, exc = _s3_is_accessible(s3_mock, s3_bucket, 'does/not/exist')
assert(not accessible)
Expand All @@ -147,6 +160,7 @@ def test__s3_is_accessible_no_key(s3_mock):
assert('Not Found' in errmsg and '404' in errmsg)


@pytest.mark.skipif('not HAS_MOTO')
def test_s3_download__noPath(s3_mock):
filename = aws_download(f's3://{s3_bucket}/{s3_key}',
local_filepath=None, cache=False)
Expand All @@ -155,11 +169,13 @@ def test_s3_download__noPath(s3_mock):
os.remove(fname)


@pytest.mark.skipif('not HAS_MOTO')
def test_s3_download__noKey(s3_mock):
with pytest.raises(ClientError):
filename = aws_download(f's3://{s3_bucket}/does/not/exist')


@pytest.mark.skipif('not HAS_MOTO')
def test_s3_download__wPath(s3_mock):
filename = aws_download(f's3://{s3_bucket}/{s3_key}',
local_filepath='newkey.txt', cache=False)
Expand All @@ -168,6 +184,7 @@ def test_s3_download__wPath(s3_mock):
os.remove(filename)


@pytest.mark.skipif('not HAS_MOTO')
def test_aws_download__wrong_cache(s3_mock):
# get the file first
with open('somekey.txt', 'w') as fp:
Expand Down
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,14 @@ python_requires = >=3.8
[options.extras_require]
all =
pillow
boto3
botocore
test =
pytest-doctestplus>=0.13
pytest-astropy
requests-mock
test_all =
moto
docs =
sphinx-astropy

Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ requires =
extras =
test: test
alldeps: all
alldeps: test_all

description =
run tests
Expand Down

0 comments on commit 5b8f6a4

Please sign in to comment.