@@ -504,7 +504,7 @@ def _filter_ffi_observations(self, observations):
504504 return obs_table [mask ]
505505
506506 @class_or_instance
507- def get_product_list_async (self , observations ):
507+ def get_product_list_async (self , observations , * , batch_size = 500 ):
508508 """
509509 Given a "Product Group Id" (column name obsid) returns a list of associated data products.
510510 Note that obsid is NOT the same as obs_id, and inputting obs_id values will result in
@@ -518,31 +518,50 @@ def get_product_list_async(self, observations):
518518 Row/Table of MAST query results (e.g. output from `query_object`)
519519 or single/list of MAST Product Group Id(s) (obsid).
520520 See description `here <https://masttest.stsci.edu/api/v0/_c_a_o_mfields.html>`__.
521+ batch_size : int, optional
522+ Default 500. Number of obsids to include in each batch request to the server.
523+ If you experience timeouts or connection errors, consider lowering this value.
521524
522525 Returns
523526 -------
524527 response : list of `~requests.Response`
528+ A list of asynchronous response objects for each batch request.
525529 """
526-
527- # getting the obsid list
530+ # Getting the obsids as a list
528531 if np .isscalar (observations ):
529- observations = np . array ( [observations ])
530- if isinstance (observations , Table ) or isinstance ( observations , Row ):
532+ observations = [observations ]
533+ elif isinstance (observations , ( Row , Table ) ):
531534 # Filter out TESS FFIs and TICA FFIs
532535 # Can only perform filtering on Row or Table because of access to `target_name` field
533536 observations = self ._filter_ffi_observations (observations )
534- observations = observations ['obsid' ]
535- if isinstance (observations , list ):
536- observations = np .array (observations )
537-
538- observations = observations [observations != "" ]
539- if observations .size == 0 :
540- raise InvalidQueryError ("Observation list is empty, no associated products." )
541-
542- service = self ._caom_products
543- params = {'obsid' : ',' .join (observations )}
544-
545- return self ._portal_api_connection .service_request_async (service , params )
537+ observations = observations ['obsid' ].tolist ()
538+
539+ # Clean and validate
540+ observations = [str (obs ).strip () for obs in observations ]
541+ observations = [obs for obs in observations if obs ]
542+ if not observations :
543+ raise InvalidQueryError ('Observation list is empty, no associated products.' )
544+
545+ # Define a helper to join obsids for each batch request
546+ def _request_joined_obsid (params ):
547+ """Join batched obsid list into comma-separated string and send async request."""
548+ pp = dict (params )
549+ vals = pp .get ('obsid' , [])
550+ pp ['obsid' ] = ',' .join (map (str , vals ))
551+ return self ._portal_api_connection .service_request_async (self ._caom_products , pp )[0 ]
552+
553+ # Perform batched requests
554+ results = utils ._batched_request (
555+ items = observations ,
556+ params = {},
557+ max_batch = batch_size ,
558+ param_key = 'obsid' ,
559+ request_func = _request_joined_obsid ,
560+ extract_func = lambda r : [r ],
561+ desc = f'Fetching products for { len (observations )} unique observations'
562+ )
563+
564+ return results
546565
547566 def filter_products (self , products , * , mrp_only = False , extension = None , ** filters ):
548567 """
@@ -1029,7 +1048,7 @@ def get_cloud_uri(self, data_product, *, include_bucket=True, full_url=False):
10291048 # Query for product URIs
10301049 return self ._cloud_connection .get_cloud_uri (data_product , include_bucket , full_url )
10311050
1032- def get_unique_product_list (self , observations ):
1051+ def get_unique_product_list (self , observations , * , batch_size = 500 ):
10331052 """
10341053 Given a "Product Group Id" (column name obsid), returns a list of associated data products with
10351054 unique dataURIs. Note that obsid is NOT the same as obs_id, and inputting obs_id values will result in
@@ -1041,13 +1060,16 @@ def get_unique_product_list(self, observations):
10411060 Row/Table of MAST query results (e.g. output from `query_object`)
10421061 or single/list of MAST Product Group Id(s) (obsid).
10431062 See description `here <https://masttest.stsci.edu/api/v0/_c_a_o_mfields.html>`__.
1063+ batch_size : int, optional
1064+ Default 500. Number of obsids to include in each batch request to the server.
1065+ If you experience timeouts or connection errors, consider lowering this value.
10441066
10451067 Returns
10461068 -------
10471069 unique_products : `~astropy.table.Table`
10481070 Table containing products with unique dataURIs.
10491071 """
1050- products = self .get_product_list (observations )
1072+ products = self .get_product_list (observations , batch_size = batch_size )
10511073 unique_products = utils .remove_duplicate_products (products , 'dataURI' )
10521074 if len (unique_products ) < len (products ):
10531075 log .info ("To return all products, use `Observations.get_product_list`" )
0 commit comments