Skip to content

Commit 515928d

Browse files
authored
Merge pull request #3080 from snbianco/ASB-21598-escape-url
Escape MAST Download URIs
2 parents 1ac230e + 487a66e commit 515928d

File tree

2 files changed

+17
-40
lines changed

2 files changed

+17
-40
lines changed

astroquery/mast/observations.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import warnings
1111
import time
1212
import os
13+
from urllib.parse import quote
1314

1415
import numpy as np
1516

@@ -534,6 +535,7 @@ def download_file(self, uri, *, local_path=None, base_url=None, cache=True, clou
534535
# create the full data URL
535536
base_url = base_url if base_url else self._portal_api_connection.MAST_DOWNLOAD_URL
536537
data_url = base_url + "?uri=" + uri
538+
escaped_url = base_url + "?uri=" + quote(uri, safe=":/")
537539

538540
# parse a local file path from local_path parameter. Use current directory as default.
539541
filename = os.path.basename(uri)
@@ -565,11 +567,11 @@ def download_file(self, uri, *, local_path=None, base_url=None, cache=True, clou
565567
status = "SKIPPED"
566568
else:
567569
log.warning("Falling back to mast download...")
568-
self._download_file(data_url, local_path,
570+
self._download_file(escaped_url, local_path,
569571
cache=cache, head_safe=True, continuation=False,
570572
verbose=verbose)
571573
else:
572-
self._download_file(data_url, local_path,
574+
self._download_file(escaped_url, local_path,
573575
cache=cache, head_safe=True, continuation=False,
574576
verbose=verbose)
575577

astroquery/mast/tests/test_mast_remote.py

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,6 @@ def test_mast_service_request_async(self):
150150
assert isinstance(responses, list)
151151

152152
def test_mast_service_request(self):
153-
154-
# clear columns config
155-
Mast._column_configs = dict()
156-
157153
service = 'Mast.Caom.Cone'
158154
params = {'ra': 184.3,
159155
'dec': 54.5,
@@ -174,9 +170,6 @@ def test_mast_service_request(self):
174170
assert len(result[np.where(result["obs_id"] == "6374399093149532160")]) == 2
175171

176172
def test_mast_query(self):
177-
# clear columns config
178-
Mast._column_configs = dict()
179-
180173
result = Mast.mast_query('Mast.Caom.Cone', ra=184.3, dec=54.5, radius=0.2)
181174

182175
# Is result in the right format
@@ -225,9 +218,6 @@ def test_observations_query_region_async(self):
225218
assert isinstance(responses, list)
226219

227220
def test_observations_query_region(self):
228-
# clear columns config
229-
Observations._column_configs = dict()
230-
231221
result = Observations.query_region("322.49324 12.16683", radius="0.005 deg")
232222
assert isinstance(result, Table)
233223
assert len(result) > 500
@@ -243,9 +233,6 @@ def test_observations_query_object_async(self):
243233
assert isinstance(responses, list)
244234

245235
def test_observations_query_object(self):
246-
# clear columns config
247-
Observations._column_configs = dict()
248-
249236
result = Observations.query_object("M8", radius=".04 deg")
250237
assert isinstance(result, Table)
251238
assert len(result) > 150
@@ -264,10 +251,6 @@ def test_observations_query_criteria_async(self):
264251
assert isinstance(responses, list)
265252

266253
def test_observations_query_criteria(self):
267-
268-
# clear columns config
269-
Observations._column_configs = dict()
270-
271254
# without position
272255
result = Observations.query_criteria(instrument_name="*WFPC2*",
273256
proposal_id=8169,
@@ -333,10 +316,6 @@ def test_observations_get_product_list_async(self):
333316
assert isinstance(responses, list)
334317

335318
def test_observations_get_product_list(self):
336-
337-
# clear columns config
338-
Observations._column_configs = dict()
339-
340319
observations = Observations.query_object("M8", radius=".04 deg")
341320
test_obs_id = str(observations[0]['obsid'])
342321
mult_obs_ids = str(observations[0]['obsid']) + ',' + str(observations[1]['obsid'])
@@ -519,6 +498,19 @@ def test_observations_download_file_cloud(self, tmp_path, in_uri):
519498
assert result == ('COMPLETE', None, None)
520499
assert Path(tmp_path, filename).exists()
521500

501+
def test_observations_download_file_escaped(self, tmp_path):
502+
# test that `download_file` correctly escapes a URI
503+
in_uri = 'mast:HLA/url/cgi-bin/fitscut.cgi?' \
504+
'red=hst_04819_65_wfpc2_f814w_pc&blue=hst_04819_65_wfpc2_f555w_pc&size=ALL&format=fits'
505+
filename = Path(in_uri).name
506+
result = Observations.download_file(uri=in_uri, local_path=tmp_path)
507+
assert result == ('COMPLETE', None, None)
508+
assert Path(tmp_path, filename).exists()
509+
510+
# check that downloaded file is a valid FITS file
511+
f = fits.open(Path(tmp_path, filename))
512+
f.close()
513+
522514
@pytest.mark.parametrize("test_data_uri, expected_cloud_uri", [
523515
("mast:HST/product/u24r0102t_c1f.fits",
524516
"s3://stpubdata/hst/public/u24r/u24r0102t/u24r0102t_c1f.fits"),
@@ -618,10 +610,7 @@ def check_result(result, row, exp_values):
618610
for k, v in exp_values.items():
619611
assert result[row][k] == v
620612

621-
# clear columns config
622-
Catalogs._column_configs = dict()
623613
in_radius = 0.1 * u.deg
624-
625614
result = Catalogs.query_region("158.47924 -7.30962",
626615
radius=in_radius,
627616
catalog="Gaia")
@@ -717,9 +706,6 @@ def check_result(result, exp_values):
717706
for k, v in exp_values.items():
718707
assert v in result[k]
719708

720-
# clear columns config
721-
Catalogs._column_configs = dict()
722-
723709
result = Catalogs.query_object("M10",
724710
radius=.001,
725711
catalog="TIC")
@@ -819,9 +805,6 @@ def check_result(result, exp_vals):
819805
for k, v in exp_vals.items():
820806
assert v in result[k]
821807

822-
# clear columns config
823-
Catalogs._column_configs = dict()
824-
825808
# without position
826809
result = Catalogs.query_criteria(catalog="Tic",
827810
Bmag=[30, 50],
@@ -897,10 +880,6 @@ def test_catalogs_query_hsc_matchid_async(self):
897880
assert isinstance(responses, list)
898881

899882
def test_catalogs_query_hsc_matchid(self):
900-
901-
# clear columns config
902-
Catalogs._column_configs = dict()
903-
904883
catalogData = Catalogs.query_object("M10",
905884
radius=.001,
906885
catalog="HSC",
@@ -921,10 +900,6 @@ def test_catalogs_get_hsc_spectra_async(self):
921900
assert isinstance(responses, list)
922901

923902
def test_catalogs_get_hsc_spectra(self):
924-
925-
# clear columns config
926-
Catalogs._column_configs = dict()
927-
928903
result = Catalogs.get_hsc_spectra()
929904
assert isinstance(result, Table)
930905
assert result[np.where(result['MatchID'] == '19657846')]

0 commit comments

Comments
 (0)