@@ -81,6 +81,37 @@ def mission(self, value):
81
81
self ._mission = value .lower () # case-insensitive
82
82
self ._service_api_connection .set_service_params (self .service_dict , f'search/{ self .mission } ' )
83
83
84
+ def _extract_products (self , response ):
85
+ """
86
+ Extract products from the response of a `~requests.Response` object.
87
+
88
+ Parameters
89
+ ----------
90
+ response : `~requests.Response`
91
+ The response object containing the products data.
92
+
93
+ Returns
94
+ -------
95
+ list
96
+ A list of products extracted from the response.
97
+ """
98
+ def normalize_products (products ):
99
+ """
100
+ Normalize the products list to ensure it is flat and not nested.
101
+ """
102
+ if products and isinstance (products [0 ], list ):
103
+ return products [0 ]
104
+ return products
105
+
106
+ if isinstance (response , list ): # multiple async responses from batching
107
+ combined = []
108
+ for resp in response :
109
+ products = normalize_products (resp .json ().get ('products' , []))
110
+ combined .extend (products )
111
+ return combined
112
+ else : # single response
113
+ return normalize_products (response .json ().get ('products' , []))
114
+
84
115
def _parse_result (self , response , * , verbose = False ): # Used by the async_to_sync decorator functionality
85
116
"""
86
117
Parse the results of a `~requests.Response` objects and return an `~astropy.table.Table` of results.
@@ -106,23 +137,11 @@ def _parse_result(self, response, *, verbose=False): # Used by the async_to_syn
106
137
if len (results ) >= self .limit :
107
138
warnings .warn ("Maximum results returned, may not include all sources within radius." ,
108
139
MaxResultsWarning )
109
- elif self .service == self ._list_products :
110
- # Results from post_list_products endpoint need to be handled differently
111
- if isinstance (response , list ): # multiple async responses from batching
112
- combined_products = []
113
- for resp in response :
114
- if self .mission == 'roman' :
115
- combined_products .extend (resp .json ().get ('products' , [])[0 ])
116
- else :
117
- combined_products .extend (resp .json ().get ('products' , []))
118
- return Table (combined_products )
119
-
120
- if self .mission == 'roman' :
121
- results = Table (response .json ()['products' ][0 ]) # single async response
122
- else :
123
- results = Table (response .json ()['products' ])
140
+ return results
124
141
125
- return results
142
+ elif self .service == self ._list_products :
143
+ products = self ._extract_products (response )
144
+ return Table (products )
126
145
127
146
def _validate_criteria (self , ** criteria ):
128
147
"""
@@ -544,7 +563,7 @@ def download_file(self, uri, *, local_path=None, cache=True, verbose=True):
544
563
545
564
# Construct the full data URL based on mission
546
565
if self .mission in ['hst' , 'jwst' , 'roman' ]:
547
- # HST and JWST have a dedicated endpoint for retrieving products
566
+ # HST, JWST, and RST have a dedicated endpoint for retrieving products
548
567
base_url = self ._service_api_connection .MISSIONS_DOWNLOAD_URL + self .mission + '/api/v0.1/retrieve_product'
549
568
keyword = 'product_name'
550
569
else :
0 commit comments