3838from stac_fastapi .types .rfc3339 import str_to_interval
3939from stac_fastapi .types .search import BaseSearchPostRequest
4040from stac_fastapi .types .stac import Collection , Collections , Item , ItemCollection
41- from stac_pydantic .links import Relations
41+ from stac_pydantic .links import Links , Relations
4242from stac_pydantic .shared import MimeTypes
4343
4444from eodag import EOProduct , SearchResult
45+ from eodag .api .collection import Collection as EodagCollection
46+ from eodag .api .collection import CollectionsList
4547from eodag .plugins .search .build_search_result import ECMWFSearch
4648from eodag .utils import deepcopy , get_geometry_from_various
4749from eodag .utils .exceptions import NoMatchingCollection as EodagNoMatchingCollection
@@ -92,19 +94,19 @@ class EodagCoreClient(CustomCoreClient):
9294 post_request_model : type [BaseModel ] = attr .ib (default = BaseSearchPostRequest )
9395 stac_metadata_model : type [CommonStacMetadata ] = attr .ib (default = CommonStacMetadata )
9496
95- def _get_collection (self , collection : dict [ str , Any ] , request : Request ) -> Collection :
97+ def _get_collection (self , collection : EodagCollection , request : Request ) -> Collection :
9698 """Convert a EODAG produt type to a STAC collection."""
9799
98100 # extend collection with external stac collection if any
99- extended_collection = Collection (deepcopy (request .app .state .ext_stac_collections .get (collection [ "ID" ] , {})))
101+ extended_collection = Collection (deepcopy (request .app .state .ext_stac_collections .get (collection . id , {})))
100102 extended_collection ["type" ] = "Collection"
101103
102- platform_value = [p for p in (collection .get ( " platform" ) or "" ).split ("," ) if p ]
103- constellation = [c for c in (collection .get ( " constellation" ) or "" ).split ("," ) if c ]
104- processing_level = [pl for pl in (collection .get ( "processing:level" ) or "" ).split ("," ) if pl ]
105- instruments = collection .get ( " instruments" ) or []
104+ platform_value = [p for p in (collection .platform or "" ).split ("," ) if p ]
105+ constellation = [c for c in (collection .constellation or "" ).split ("," ) if c ]
106+ processing_level = [pl for pl in (collection .processing_level or "" ).split ("," ) if pl ]
107+ instruments = collection .instruments or []
106108
107- federation_backends = request .app .state .dag .available_providers (collection [ " _id" ])
109+ federation_backends = request .app .state .dag .providers . filter (collection . _id ). names
108110
109111 summaries : dict [str , Any ] = {
110112 "platform" : platform_value ,
@@ -114,31 +116,31 @@ def _get_collection(self, collection: dict[str, Any], request: Request) -> Colle
114116 "federation:backends" : federation_backends ,
115117 }
116118 extended_collection ["summaries" ] = {
117- ** collection . get ( "summaries" , {}),
119+ ** ( getattr ( collection , "summaries" , {}) or {}),
118120 ** {k : v for k , v in summaries .items () if v },
119121 }
120122
121123 extended_collection ["extent" ] = {
122124 "spatial" : extended_collection .get ("extent" , {}).get ("spatial" )
123- or collection .get ( " extent" , {}). get ( " spatial" )
125+ or collection .extent . spatial . to_dict ( )
124126 or {"bbox" : [[- 180.0 , - 90.0 , 180.0 , 90.0 ]]},
125127 "temporal" : extended_collection .get ("extent" , {}).get ("temporal" )
126- or collection .get ( " extent" , {}). get ( " temporal" )
128+ or collection .extent . temporal . to_dict ( )
127129 or {"interval" : [[None , None ]]},
128130 }
129131
130132 for key in ["license" , "description" , "title" ]:
131- if value := collection . get ( key ):
133+ if value := getattr ( collection , key ):
132134 extended_collection [key ] = value
133135
134- keywords = collection .get ( " keywords" , [])
136+ keywords = collection .keywords or []
135137 keywords = keywords .split ("," ) if isinstance (keywords , str ) else keywords
136138 try :
137139 extended_collection ["keywords" ] = list (set (keywords + extended_collection .get ("keywords" , [])))
138140 except TypeError as e :
139- logger .warning ("Could not merge keywords from external collection for %s: %s" , collection [ "ID" ] , str (e ))
141+ logger .warning ("Could not merge keywords from external collection for %s: %s" , collection . id , str (e ))
140142
141- extended_collection ["id" ] = collection [ "ID" ]
143+ extended_collection ["id" ] = collection . id
142144
143145 # keep only federation backends which allow order mechanism
144146 # to create "retrieve" collection links from them
@@ -155,14 +157,14 @@ def has_ecmwf_search_plugin(federation_backends, request):
155157 ):
156158 extension_names .remove ("CollectionOrderExtension" )
157159
160+ extra_links = (collection .links or Links ([])).root
161+ extended_coll_links = Links (extended_collection .get ("links" , [])).root
158162 extended_collection ["links" ] = CollectionLinks (
159163 collection_id = extended_collection ["id" ],
160164 request = request ,
161- ).get_links (
162- extensions = extension_names , extra_links = collection .get ("links" , []) + extended_collection .get ("links" , [])
163- )
165+ ).get_links (extensions = extension_names , extra_links = extra_links + extended_coll_links )
164166
165- return extended_collection
167+ return Collection ( ** extended_collection )
166168
167169 def _search_base (self , search_request : BaseSearchPostRequest , request : Request ) -> ItemCollection :
168170 eodag_args = prepare_search_base_args (search_request = search_request , model = self .stac_metadata_model )
@@ -175,11 +177,12 @@ def _search_base(self, search_request: BaseSearchPostRequest, request: Request)
175177
176178 # check if the collection exists
177179 if collection := eodag_args .get ("collection" ):
178- all_pt = request .app .state .dag .list_collections (fetch_providers = False )
180+ all_coll = request .app .state .dag .list_collections (fetch_providers = False )
179181 # only check the first collection (EODAG search only support a single collection)
180- existing_pt = [pt for pt in all_pt if pt [ "ID" ] == collection ]
181- if not existing_pt :
182+ existing_coll = [coll for coll in all_coll if coll . id == collection ]
183+ if not existing_coll :
182184 raise NoMatchingCollection (f"Collection { collection } does not exist." )
185+ eodag_args ["collection" ] = existing_coll [0 ].id
183186 else :
184187 raise HTTPException (status_code = 400 , detail = "A collection is required" )
185188
@@ -265,7 +268,7 @@ async def all_collections(
265268 provider = parsed_query .get ("federation:backends" )
266269 provider = provider [0 ] if isinstance (provider , list ) else provider
267270
268- all_pt = request .app .state .dag .list_collections (provider = provider , fetch_providers = False )
271+ all_colls = request .app .state .dag .list_collections (provider = provider , fetch_providers = False )
269272
270273 # datetime & free-text-search filters
271274 if any ((q , datetime )):
@@ -279,31 +282,32 @@ async def all_collections(
279282 guessed_collections = request .app .state .dag .guess_collection (
280283 free_text = free_text , start_date = start , end_date = end
281284 )
285+ guessed_collections_ids = [coll .id for coll in guessed_collections ]
282286 except EodagNoMatchingCollection :
283- collections = []
287+ collections = CollectionsList ([])
284288 else :
285- collections = [ pt for pt in all_pt if pt [ "ID" ] in guessed_collections ]
289+ collections = CollectionsList ([ coll for coll in all_colls if coll . id in guessed_collections_ids ])
286290 else :
287- collections = all_pt
291+ collections = all_colls
288292
289- collections = [self ._get_collection (pt , request ) for pt in collections ]
293+ formatted_collections = [self ._get_collection (coll , request ) for coll in collections ]
290294
291295 # bbox filter
292296 if bbox :
293297 bbox_geom = get_geometry_from_various (geometry = bbox )
294298
295299 default_extent = [[- 180.0 , - 90.0 , 180.0 , 90.0 ]]
296- collections = [
300+ formatted_collections = [
297301 c
298- for c in collections
302+ for c in formatted_collections
299303 if check_poly_is_point (
300304 get_geometry_from_various ( # type: ignore
301305 geometry = c .get ("extent" , {}).get ("spatial" , {}).get ("bbox" , default_extent )[0 ]
302306 )
303307 ).intersection (bbox_geom )
304308 ]
305309
306- total = len (collections )
310+ total = len (formatted_collections )
307311
308312 links = [
309313 {
@@ -318,7 +322,7 @@ async def all_collections(
318322 limit = limit if limit is not None else 10
319323 offset = offset if offset is not None else 0
320324
321- collections = collections [offset : offset + limit ]
325+ formatted_collections = formatted_collections [offset : offset + limit ]
322326
323327 if offset + limit < total :
324328 next_link = {"body" : {"limit" : limit , "offset" : offset + limit }}
@@ -337,10 +341,10 @@ async def all_collections(
337341 links .extend (paging_links )
338342
339343 return Collections (
340- collections = collections ,
344+ collections = formatted_collections ,
341345 links = links ,
342346 numberMatched = total ,
343- numberReturned = len (collections ),
347+ numberReturned = len (formatted_collections ),
344348 )
345349
346350 async def get_collection (self , collection_id : str , request : Request , ** kwargs : Any ) -> Collection :
@@ -356,7 +360,7 @@ async def get_collection(self, collection_id: str, request: Request, **kwargs: A
356360 :raises NotFoundError: If the collection does not exist.
357361 """
358362 collection = next (
359- (pt for pt in request .app .state .dag .list_collections (fetch_providers = False ) if pt [ "ID" ] == collection_id ),
363+ (c for c in request .app .state .dag .list_collections (fetch_providers = False ) if c . id == collection_id ),
360364 None ,
361365 )
362366 if collection is None :
@@ -422,7 +426,7 @@ async def item_collection(
422426 item_collection = self ._search_base (search_request , request )
423427 extension_names = [type (ext ).__name__ for ext in self .extensions ]
424428 links = ItemCollectionLinks (collection_id = collection_id , request = request ).get_links (
425- extensions = extension_names , extra_links = item_collection ["links" ]
429+ extensions = extension_names , extra_links = Links ( item_collection ["links" ]). root
426430 )
427431 item_collection ["links" ] = links
428432 return item_collection
0 commit comments