10
10
import uuid
11
11
import json
12
12
import time
13
+ import re
13
14
14
15
import numpy as np
15
16
18
19
from astropy .table import Table , vstack , MaskedColumn
19
20
from astropy .utils import deprecated
20
21
21
- from ..query import BaseQuery , QueryWithLogin
22
+ from ..query import BaseQuery , QueryWithLogin , AstroQuery , to_cache
22
23
from ..utils import async_to_sync
23
24
from ..utils .class_or_instance import class_or_instance
24
25
from ..exceptions import InputWarning , NoResultsWarning , RemoteServiceError
@@ -211,7 +212,39 @@ def _request(self, method, url, params=None, data=None, headers=None,
211
212
212
213
return all_responses
213
214
214
- def _get_col_config (self , service , fetch_name = None ):
215
+ def _request_w_cache (self , method , url , data = None , headers = None , retrieve_all = True ,
216
+ cache = False , cache_opts = None ):
217
+ # Note: the method only exposes 4 parameters of the underlying _request() function
218
+ # to play nice with existing mocks
219
+ # Caching: follow BaseQuery._request()'s pattern, which uses an AstroQuery object
220
+ if not cache :
221
+ response = self ._request (method , url , data = data , headers = headers , retrieve_all = retrieve_all )
222
+ else :
223
+ cacher = self ._get_cacher (method , url , data , headers , retrieve_all )
224
+ response = cacher .from_cache (self .cache_location )
225
+ if not response :
226
+ response = self ._request (method , url , data = data , headers = headers , retrieve_all = retrieve_all )
227
+ to_cache (response , cacher .request_file (self .cache_location ))
228
+ return response
229
+
230
+ def _get_cacher (self , method , url , data , headers , retrieve_all ):
231
+ """
232
+ Return an object that can cache the HTTP request based on the supplied arguments
233
+ """
234
+
235
+ # cacheBreaker parameter (to underlying MAST service) is not relevant (and breaks) local caching
236
+ # remove it from part of the cache key
237
+ data_no_cache_breaker = re .sub (r'^(.+)cacheBreaker%22%3A%20%22.+%22' , r'\1' , data )
238
+ # include retrieve_all as part of the cache key by appending it to data
239
+ # it cannot be added as part of req_kwargs dict, as it will be rejected by AstroQuery
240
+ data_w_retrieve_all = data_no_cache_breaker + " retrieve_all={}" .format (retrieve_all )
241
+ req_kwargs = dict (
242
+ data = data_no_cache_breaker ,
243
+ headers = headers
244
+ )
245
+ return AstroQuery (method , url , ** req_kwargs )
246
+
247
+ def _get_col_config (self , service , fetch_name = None , cache = False ):
215
248
"""
216
249
Gets the columnsConfig entry for given service and stores it in `self._column_configs`.
217
250
@@ -247,7 +280,7 @@ def _get_col_config(self, service, fetch_name=None):
247
280
if more :
248
281
mashup_request = {'service' : all_name , 'params' : {}, 'format' : 'extjs' }
249
282
req_string = _prepare_service_request_string (mashup_request )
250
- response = self ._request ("POST" , self .MAST_REQUEST_URL , data = req_string , headers = headers )
283
+ response = self ._request_w_cache ("POST" , self .MAST_REQUEST_URL , data = req_string , headers = headers , cache = cache )
251
284
json_response = response [0 ].json ()
252
285
253
286
self ._column_configs [service ].update (json_response ['data' ]['Tables' ][0 ]
@@ -301,7 +334,7 @@ def _parse_result(self, responses, verbose=False):
301
334
return all_results
302
335
303
336
@class_or_instance
304
- def service_request_async (self , service , params , pagesize = None , page = None , ** kwargs ):
337
+ def service_request_async (self , service , params , pagesize = None , page = None , cache = False , cache_opts = None , ** kwargs ):
305
338
"""
306
339
Given a Mashup service and parameters, builds and excecutes a Mashup query.
307
340
See documentation `here <https://mast.stsci.edu/api/v0/class_mashup_1_1_mashup_request.html>`__
@@ -321,6 +354,10 @@ def service_request_async(self, service, params, pagesize=None, page=None, **kwa
321
354
Default None.
322
355
Can be used to override the default behavior of all results being returned to obtain
323
356
a specific page of results.
357
+ cache : Boolean, optional
358
+ try to use cached the query result if set to True
359
+ cache_opts : dict, optional
360
+ cache options, details TBD, e.g., cache expiration policy, etc.
324
361
**kwargs :
325
362
See MashupRequest properties
326
363
`here <https://mast.stsci.edu/api/v0/class_mashup_1_1_mashup_request.html>`__
@@ -334,7 +371,7 @@ def service_request_async(self, service, params, pagesize=None, page=None, **kwa
334
371
# setting self._current_service
335
372
if service not in self ._column_configs .keys ():
336
373
fetch_name = kwargs .pop ('fetch_name' , None )
337
- self ._get_col_config (service , fetch_name )
374
+ self ._get_col_config (service , fetch_name , cache )
338
375
self ._current_service = service
339
376
340
377
# setting up pagination
@@ -360,12 +397,12 @@ def service_request_async(self, service, params, pagesize=None, page=None, **kwa
360
397
mashup_request [prop ] = value
361
398
362
399
req_string = _prepare_service_request_string (mashup_request )
363
- response = self ._request ("POST" , self .MAST_REQUEST_URL , data = req_string , headers = headers ,
364
- retrieve_all = retrieve_all )
400
+ response = self ._request_w_cache ("POST" , self .MAST_REQUEST_URL , data = req_string , headers = headers ,
401
+ retrieve_all = retrieve_all , cache = cache , cache_opts = cache_opts )
365
402
366
403
return response
367
404
368
- def build_filter_set (self , column_config_name , service_name = None , ** filters ):
405
+ def build_filter_set (self , column_config_name , service_name = None , cache = False , ** filters ):
369
406
"""
370
407
Takes user input dictionary of filters and returns a filterlist that the Mashup can understand.
371
408
@@ -393,7 +430,7 @@ def build_filter_set(self, column_config_name, service_name=None, **filters):
393
430
service_name = column_config_name
394
431
395
432
if not self ._column_configs .get (service_name ):
396
- self ._get_col_config (service_name , fetch_name = column_config_name )
433
+ self ._get_col_config (service_name , fetch_name = column_config_name , cache = cache )
397
434
398
435
caom_col_config = self ._column_configs [service_name ]
399
436
0 commit comments