4444
4545from eodag import SearchResult
4646from eodag .api .core import DEFAULT_ITEMS_PER_PAGE
47+ from eodag .plugins .search .build_search_result import ECMWFSearch
4748from eodag .utils import deepcopy , get_geometry_from_various
48- from eodag .utils .exceptions import NoMatchingProductType
49+ from eodag .utils .exceptions import NoMatchingProductType as EodagNoMatchingProductType
4950from stac_fastapi .eodag .config import get_settings
5051from stac_fastapi .eodag .cql_evaluate import EodagEvaluator
51- from stac_fastapi .eodag .errors import ResponseSearchError
52+ from stac_fastapi .eodag .errors import NoMatchingProductType , ResponseSearchError
5253from stac_fastapi .eodag .landing_page import CustomCoreClient
5354from stac_fastapi .eodag .models .links import (
5455 CollectionLinks ,
@@ -132,10 +133,25 @@ def _get_collection(self, product_type: dict[str, Any], request: Request) -> Col
132133
133134 collection ["id" ] = product_type ["ID" ]
134135
136+ # keep only federation backends which allow order mechanism
137+ # to create "retrieve" collection links from them
138+ def has_ecmwf_search_plugin (federation_backends , request ):
139+ for fb in federation_backends :
140+ search_plugins = request .app .state .dag ._plugins_manager .get_search_plugins (provider = fb )
141+ if any (isinstance (plugin , ECMWFSearch ) for plugin in search_plugins ):
142+ return True
143+ return False
144+
135145 extension_names = [type (ext ).__name__ for ext in self .extensions ]
136- collection ["links" ] = CollectionLinks (collection_id = collection ["id" ], request = request ).get_links (
137- extensions = extension_names , extra_links = product_type .get ("links" , []) + collection .get ("links" , [])
138- )
146+ if self .extension_is_enabled ("CollectionOrderExtension" ) and not has_ecmwf_search_plugin (
147+ federation_backends , request
148+ ):
149+ extension_names .remove ("CollectionOrderExtension" )
150+
151+ collection ["links" ] = CollectionLinks (
152+ collection_id = collection ["id" ],
153+ request = request ,
154+ ).get_links (extensions = extension_names , extra_links = product_type .get ("links" , []) + collection .get ("links" , []))
139155
140156 collection ["providers" ] = merge_providers (
141157 collection .get ("providers" , []) + [get_provider_dict (request , fb ) for fb in federation_backends ]
@@ -144,40 +160,42 @@ def _get_collection(self, product_type: dict[str, Any], request: Request) -> Col
144160 return collection
145161
146162 def _search_base (self , search_request : BaseSearchPostRequest , request : Request ) -> ItemCollection :
163+ eodag_args = prepare_search_base_args (search_request = search_request , model = self .stac_metadata_model )
164+
165+ request .state .eodag_args = eodag_args
166+
147167 # check if the collection exists
148- if search_request . collections :
168+ if product_type := eodag_args . get ( "productType" ) :
149169 all_pt = request .app .state .dag .list_product_types (fetch_providers = False )
150170 # only check the first collection (EODAG search only support a single collection)
151- existing_pt = [pt for pt in all_pt if pt ["ID" ] == search_request . collections [ 0 ] ]
171+ existing_pt = [pt for pt in all_pt if pt ["ID" ] == product_type ]
152172 if not existing_pt :
153- raise NoMatchingProductType (f"Collection { search_request . collections [ 0 ] } does not exist." )
173+ raise NoMatchingProductType (f"Collection { product_type } does not exist." )
154174 else :
155175 raise HTTPException (status_code = 400 , detail = "A collection is required" )
156176
157177 # get products by ids
158- if search_request . ids :
178+ if ids := eodag_args . pop ( " ids" , []) :
159179 search_result = SearchResult ([])
160- ids = search_request .ids
161180 for item_id in ids :
162- search_request .ids = [item_id ]
163- base_args = prepare_search_base_args (search_request = search_request , model = self .stac_metadata_model )
164- search_result .extend (request .app .state .dag .search (** base_args ))
181+ eodag_args ["id" ] = item_id
182+ search_result .extend (request .app .state .dag .search (** eodag_args ))
165183 search_result .number_matched = len (search_result )
166184 else :
167185 # search without ids
168- base_args = prepare_search_base_args (search_request = search_request , model = self .stac_metadata_model )
169- search_result = request .app .state .dag .search (** base_args )
186+ search_result = request .app .state .dag .search (** eodag_args )
170187
171188 if search_result .errors and not len (search_result ):
172189 raise ResponseSearchError (search_result .errors , self .stac_metadata_model )
173190
174191 request_json = loop .run_until_complete (request .json ()) if request .method == "POST" else None
175192
176193 features : list [Item ] = []
194+ extension_names = [type (ext ).__name__ for ext in self .extensions ]
177195
178196 for product in search_result :
179197 feature = create_stac_item (
180- product , self .stac_metadata_model , self .extension_is_enabled , request , request_json
198+ product , self .stac_metadata_model , self .extension_is_enabled , request , extension_names , request_json
181199 )
182200 features .append (feature )
183201
@@ -198,7 +216,6 @@ def _search_base(self, search_request: BaseSearchPostRequest, request: Request)
198216 ):
199217 next_page = search_request .page + 1
200218
201- extension_names = [type (ext ).__name__ for ext in self .extensions ]
202219 collection ["links" ] = PagingLinks (
203220 request = request ,
204221 next = next_page ,
@@ -246,7 +263,7 @@ async def all_collections(
246263 guessed_product_types = request .app .state .dag .guess_product_type (
247264 free_text = q , missionStartDate = start , missionEndDate = end
248265 )
249- except NoMatchingProductType :
266+ except EodagNoMatchingProductType :
250267 product_types = []
251268 else :
252269 product_types = [pt for pt in all_pt if pt ["ID" ] in guessed_product_types ]
@@ -416,11 +433,11 @@ def get_search(
416433
417434 if filter_expr :
418435 if filter_lang == "cql2-text" :
419- ast = parse_cql2_text (filter_expr )
420- base_args [ "filter_expr" ] = str2json ( "filter_expr" , to_cql2 ( ast )) # type: ignore
421- base_args [ "filter-lang" ] = "cql2-json"
422- elif filter_lang == "cql-json" :
423- base_args ["filter_expr " ] = str2json ( filter_expr )
436+ filter_expr = to_cql2 ( parse_cql2_text (filter_expr ) )
437+ filter_lang = "cql2-json"
438+
439+ base_args [ "filter" ] = str2json ( "filter_expr" , filter_expr )
440+ base_args ["filter_lang " ] = "cql2-json"
424441
425442 # Remove None values from dict
426443 clean = {}
@@ -433,7 +450,7 @@ def get_search(
433450 except ValidationError as err :
434451 raise HTTPException (status_code = 400 , detail = f"Invalid parameters provided { err } " ) from err
435452
436- return self .post_search (search_request , request )
453+ return self ._search_base (search_request , request )
437454
438455 async def get_item (self , item_id : str , collection_id : str , request : Request , ** kwargs : Any ) -> Item :
439456 """
@@ -555,9 +572,8 @@ def prepare_search_base_args(search_request: BaseSearchPostRequest, model: type[
555572 if search_request .collections :
556573 base_args ["productType" ] = search_request .collections [0 ]
557574
558- # handle only one id from here (pre-filtered in _search_base)
559575 if search_request .ids :
560- base_args ["id " ] = search_request .ids [ 0 ]
576+ base_args ["ids " ] = search_request .ids
561577
562578 # merge all eodag search arguments
563579 base_args = base_args | sort_by | eodag_filter | eodag_query
0 commit comments