Skip to content

Commit 97e5c90

Browse files
committed
Merge pull request #1 from keflavich/lcogt
Thanks for refactoring. Useful to know those tips.
2 parents 7a11c5e + 107af7c commit 97e5c90

File tree

3 files changed

+59
-104
lines changed

3 files changed

+59
-104
lines changed

astropy_helpers

Submodule astropy_helpers updated 50 files

astroquery/lcogt/core.py

Lines changed: 54 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -79,40 +79,27 @@
7979
import astropy.io.votable as votable
8080

8181
from ..query import BaseQuery
82-
from ..utils import commons
82+
from ..utils import commons, async_to_sync
8383
from . import conf
8484
from ..exceptions import TableParseError
8585

8686
__all__ = ['Lcogt', 'LcogtClass']
8787

8888

89+
@async_to_sync
8990
class LcogtClass(BaseQuery):
9091
LCOGT_URL = conf.server
9192
TIMEOUT = conf.timeout
9293
ROW_LIMIT = conf.row_limit
9394

94-
def query_object(self, objstr, catalog=None, verbose=False):
95-
"""
96-
Queries the LCOGT public archive hosted at NASA/IPAC archive on target name
97-
and returns the result as a `~astropy.table.Table`.
98-
See examples below.
99-
100-
Parameters
101-
----------
102-
objstr : str
103-
name of object to be queried
104-
catalog : str
105-
name of the catalog to use. 'lco_img' for image meta data; 'lco_cat' for photometry.
95+
@property
96+
def catalogs(self):
97+
""" immutable catalog listing """
98+
return {'lco_cat' : 'Photometry archive from LCOGT',
99+
'lco_img' : 'Image metadata archive from LCOGT'}
106100

107-
Returns
108-
-------
109-
table : `~astropy.table.Table`
110-
Query results table
111-
"""
112-
response = self.query_object_async(objstr, catalog=catalog)
113-
return self._parse_result(response, verbose=verbose)
114-
115-
def query_object_async(self, objstr, catalog=None):
101+
def query_object_async(self, objstr, catalog=None, cache=True,
102+
get_query_payload=False):
116103
"""
117104
Serves the same function as `query_object`, but
118105
only collects the reponse from the LCOGT IPAC archive and returns.
@@ -121,79 +108,36 @@ def query_object_async(self, objstr, catalog=None):
121108
----------
122109
objstr : str
123110
name of object to be queried
111+
catalog : str
112+
name of the catalog to use. 'lco_img' for image meta data;
113+
'lco_cat' for photometry.
124114
125115
Returns
126116
-------
127117
response : `requests.Response`
128118
Response of the query from the server
129119
"""
130120
if catalog is None:
131-
raise Exception("Catalogue name is required!")
121+
raise ValueError("Catalogue name is required!")
122+
if catalog not in self.catalogs:
123+
raise ValueError("Catalog name must be one of {0}"
124+
.format(self.catalogs))
125+
132126
request_payload = self._args_to_payload(catalog)
133127
request_payload['objstr'] = objstr
134-
response = commons.send_request(Lcogt.LCOGT_URL, request_payload,
135-
Lcogt.TIMEOUT, request_type='GET')
136-
return response
137-
138-
def query_region(self, coordinates=None, catalog=None, spatial=None, radius=None, width=None, polygon=None,
139-
get_query_payload=False, verbose=False):
140-
"""
141-
This function can be used to perform either cone, box, polygon or
142-
all-sky search in the LCOGT public archive hosted by the NASA/IPAC Archive.
143-
144-
Parameters
145-
----------
146-
coordinates : str, `astropy.coordinates` object
147-
Gives the position of the center of the cone or box if
148-
performing a cone or box search. The string can give coordinates
149-
in various coordinate systems, or the name of a source that will
150-
be resolved on the server (see `here
151-
<http://irsa.ipac.caltech.edu/search_help.html>`_ for more
152-
details). Required if spatial is ``'Cone'`` or ``'Box'``. Optional
153-
if spatial is ``'Polygon'``.
154-
catalog : str
155-
The catalog to be used. Either ``lco_img`` for image metadata or ``lco_cat``
156-
for photometry.
157-
spatial : str
158-
Type of spatial query: ``'Cone'``, ``'Box'``, ``'Polygon'``, and
159-
``'All-Sky'``. If missing then defaults to ``'Cone'``.
160-
radius : str or `~astropy.units.Quantity` object, [optional for spatial is ``'Cone'``]
161-
The string must be parsable by `~astropy.coordinates.Angle`. The
162-
appropriate `~astropy.units.Quantity` object from
163-
`astropy.units` may also be used. Defaults to 10 arcsec.
164-
width : str, `~astropy.units.Quantity` object [Required for spatial is ``'Polygon'``.]
128+
if get_query_payload:
129+
return request_payload
165130

166-
The string must be parsable by `~astropy.coordinates.Angle`. The
167-
appropriate `~astropy.units.Quantity` object from `astropy.units`
168-
may also be used.
169-
polygon : list, [Required for spatial is ``'Polygon'``]
170-
A list of ``(ra, dec)`` pairs (as tuples), in decimal degrees,
171-
outlinining the polygon to search in. It can also be a list of
172-
`astropy.coordinates` object or strings that can be parsed by
173-
`astropy.coordinates.ICRS`.
174-
get_query_payload : bool, optional
175-
If `True` then returns the dictionary sent as the HTTP request.
176-
Defaults to `False`.
177-
verbose : bool, optional.
178-
If `True` then displays warnings when the returned VOTable does not
179-
conform to the standard. Defaults to `False`.
131+
response = self._request(method='GET', url=self.LCOGT_URL,
132+
params=request_payload, timeout=self.TIMEOUT,
133+
cache=cache)
134+
return response
180135

181-
Returns
182-
-------
183-
table : `~astropy.table.Table`
184-
A table containing the results of the query
185-
"""
186-
response = self.query_region_async(coordinates, catalog=catalog,
187-
spatial=spatial, radius=radius,
188-
width=width, polygon=polygon,
189-
get_query_payload=get_query_payload)
190-
if get_query_payload:
191-
return response
192-
return self._parse_result(response, verbose=verbose)
193136

194137
def query_region_async(self, coordinates=None, catalog=None,
195-
spatial='Cone', radius=10 * u.arcsec, width=None,
196-
polygon=None, get_query_payload=False):
138+
spatial='Cone', radius=10*u.arcsec, width=None,
139+
polygon=None, get_query_payload=False, cache=True,
140+
):
197141
"""
198142
This function serves the same purpose as
199143
:meth:`~astroquery.irsa.LcogtClass.query_region`, but returns the raw
@@ -210,16 +154,18 @@ def query_region_async(self, coordinates=None, catalog=None,
210154
details). Required if spatial is ``'Cone'`` or ``'Box'``. Optional
211155
if spatial is ``'Polygon'``.
212156
catalog : str
213-
The catalog to be used. Either ``'lco_img'`` for image metadata or ``'lco_cat'``
214-
for photometry.
157+
The catalog to be used. Either ``'lco_img'`` for image metadata or
158+
``'lco_cat'`` for photometry.
215159
spatial : str
216160
Type of spatial query: ``'Cone'``, ``'Box'``, ``'Polygon'``, and
217161
``'All-Sky'``. If missing then defaults to ``'Cone'``.
218-
radius : str or `~astropy.units.Quantity` object, [optional for spatial is ``'Cone'``]
162+
radius : str or `~astropy.units.Quantity` object, [optional for \\
163+
spatial is ``'Cone'``]
219164
The string must be parsable by `~astropy.coordinates.Angle`. The
220165
appropriate `~astropy.units.Quantity` object from
221166
`astropy.units` may also be used. Defaults to 10 arcsec.
222-
width : str, `~astropy.units.Quantity` object [Required for spatial is ``'Polygon'``.]
167+
width : str, `~astropy.units.Quantity` object [Required for spatial \\
168+
is ``'Polygon'``.]
223169
The string must be parsable by `~astropy.coordinates.Angle`. The
224170
appropriate `~astropy.units.Quantity` object from `astropy.units`
225171
may also be used.
@@ -238,7 +184,11 @@ def query_region_async(self, coordinates=None, catalog=None,
238184
The HTTP response returned from the service
239185
"""
240186
if catalog is None:
241-
raise Exception("Catalogue name is required!")
187+
raise ValueError("Catalogue name is required!")
188+
if catalog not in self.catalogs:
189+
raise ValueError("Catalog name must be one of {0}"
190+
.format(self.catalogs))
191+
242192

243193
request_payload = self._args_to_payload(catalog)
244194
request_payload.update(self._parse_spatial(spatial=spatial,
@@ -248,8 +198,9 @@ def query_region_async(self, coordinates=None, catalog=None,
248198

249199
if get_query_payload:
250200
return request_payload
251-
response = commons.send_request(Lcogt.LCOGT_URL, request_payload,
252-
Lcogt.TIMEOUT, request_type='GET')
201+
response = self._request(method='GET', url=self.LCOGT_URL,
202+
params=request_payload, timeout=self.TIMEOUT,
203+
cache=cache)
253204
return response
254205

255206
def _parse_spatial(self, spatial, coordinates, radius=None, width=None,
@@ -307,15 +258,20 @@ def _parse_spatial(self, spatial, coordinates, radius=None, width=None,
307258
request_payload['size'] = width.to(u.arcsec).value
308259
elif spatial == 'Polygon':
309260
if coordinates is not None:
310-
request_payload['objstr'] = coordinates if not commons._is_coordinate(coordinates) else _parse_coordinates(coordinates)
261+
request_payload['objstr'] = (coordinates if not
262+
commons._is_coordinate(coordinates)
263+
else
264+
_parse_coordinates(coordinates))
311265
try:
312266
coordinates_list = [_parse_coordinates(c) for c in polygon]
313267
except (ValueError, TypeError):
314-
coordinates_list = [_format_decimal_coords(*_pair_to_deg(pair)) for pair in polygon]
268+
coordinates_list = [_format_decimal_coords(*_pair_to_deg(pair))
269+
for pair in polygon]
315270
request_payload['polygon'] = ','.join(coordinates_list)
316271
else:
317-
raise ValueError("Unrecognized spatial query type. " +
318-
"Must be one of `Cone`, `Box`, `Polygon`, or `All-Sky`.")
272+
raise ValueError("Unrecognized spatial query type. "
273+
"Must be one of `Cone`, `Box`, "
274+
"`Polygon`, or `All-Sky`.")
319275

320276
request_payload['spatial'] = spatial
321277

@@ -382,8 +338,9 @@ def _parse_result(self, response, verbose=False):
382338
except Exception as ex:
383339
self.response = response
384340
self.table_parse_error = ex
385-
raise TableParseError("Failed to parse LCOGT votable! The raw response can be found "
386-
"in self.response, and the error in self.table_parse_error.")
341+
raise TableParseError("Failed to parse LCOGT votable! The raw "
342+
" response can be found in self.response,"
343+
" and the error in self.table_parse_error.")
387344

388345
# Convert to astropy.table.Table instance
389346
table = first_table.to_table()
@@ -405,16 +362,13 @@ def list_catalogs(self):
405362
be used in query functions, and the value is the verbose description
406363
of the catalog.
407364
"""
408-
catalogs = {'lco_cat' : 'Photometry archive from LCOGT',
409-
'lco_img' : 'Image metadata archive from LCOGT'}
410-
return catalogs
365+
return self.catalogs
411366

412367
def print_catalogs(self):
413368
"""
414369
Display a table of the catalogs in the LCOGT Gator tool.
415370
"""
416-
catalogs = self.list_catalogs()
417-
for catname in catalogs:
371+
for catname in self.catalogs:
418372
print("{:30s} {:s}".format(catname, catalogs[catname]))
419373

420374
Lcogt = LcogtClass()

astroquery/lcogt/tests/test_lcogt.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
'Polygon': 'Polygon.xml'}
2121

2222
OBJ_LIST = ["m31", "00h42m44.330s +41d16m07.50s",
23-
commons.GalacticCoordGenerator(l=121.1743, b=-21.5733, unit=(u.deg, u.deg))]
23+
commons.GalacticCoordGenerator(l=121.1743, b=-21.5733, unit=(u.deg,
24+
u.deg))]
2425

2526

2627
def data_path(filename):
@@ -31,11 +32,11 @@ def data_path(filename):
3132
@pytest.fixture
3233
def patch_get(request):
3334
mp = request.getfuncargvalue("monkeypatch")
34-
mp.setattr(requests, 'get', get_mockreturn)
35+
mp.setattr(lcogt.core.Lcogt, '_request', get_mockreturn)
3536
return mp
3637

3738

38-
def get_mockreturn(url, params=None, timeout=10, **kwargs):
39+
def get_mockreturn(method, url, params=None, timeout=10, cache=True, **kwargs):
3940
filename = data_path(DATA_FILES[params['spatial']])
4041
content = open(filename, 'rb').read()
4142
return MockResponse(content, **kwargs)

0 commit comments

Comments
 (0)