1818It includes an API endpoint, utility functions, and initialization for accessing EODataAccessGateway.
1919"""
2020
21- # pylint: disable=redefined-builtin
2221import json
22+ import threading
2323import traceback
24+
25+ # pylint: disable=redefined-builtin
26+ from collections import defaultdict
2427from typing import Annotated , List , Literal , Union
2528
2629import requests
3740from rs_server_cadip .cadip_utils import (
3841 CADIP_CONFIG ,
3942 cadip_map_mission ,
43+ cadip_stac_mapper ,
4044 link_assets_to_session ,
4145 prepare_collection ,
4246 read_conf ,
5054 set_eodag_auth_token ,
5155)
5256from rs_server_common .data_retrieval .provider import CreateProviderFailed
57+ from rs_server_common .rspy_models import Item
5358from rs_server_common .stac_api_common import (
5459 CollectionType ,
5560 DateTimeType ,
@@ -97,15 +102,15 @@ def __init__(self, request: Request | None = None, readwrite: Literal["r", "w"]
97102 self .sortby = "-published"
98103
99104 @handle_exceptions
100- def process_search (
105+ def process_search ( # type: ignore
101106 self ,
102107 collection : dict ,
103108 odata_params : dict ,
104109 limit : int ,
105110 page : int ,
106111 ) -> stac_pydantic .ItemCollection :
107- """Do the search for the given collection and OData parameters."""
108- session_data = process_session_search (
112+ """Search cadip sessions the given collection and OData parameters."""
113+ return process_session_search (
109114 self .request ,
110115 collection .get ("station" , "cadip" ),
111116 odata_params .get ("SessionId" , []),
@@ -116,18 +121,30 @@ def process_search(
116121 limit ,
117122 page ,
118123 )
119- if not session_data .features :
120- # If there are no sessions, don't proceed to assets allocation
121- return session_data
122124
123- # To be updated with proper ('')
124- features_ids = ", " .join (feature .id for feature in session_data .features )
125+ @handle_exceptions
126+ def process_asset_search (
127+ self ,
128+ station : str ,
129+ session_features : list [Item ],
130+ ):
131+ """
132+ Search cadip files for each input cadip session and their associated station.
133+ Update input session assets with their associated files.
134+
135+ Args:
136+ station (str): station identifier
137+ session_features (list[Item]): sessions as Item objects
138+ """
139+
140+ # Join session ids with ', '
141+ features_ids = ", " .join (feature .id for feature in session_features )
125142
126143 assets : list [dict ] = []
127144 page = 1
128145 while True :
129146 chunked_assets = process_files_search (
130- collection . get ( " station" , "cadip" ) ,
147+ station ,
131148 features_ids ,
132149 map_to_session = True ,
133150 page = page ,
@@ -141,8 +158,49 @@ def process_search(
141158 # If assets are equal to maximum limit, then send another request for the next page
142159 page += 1
143160
144- with open (CADIP_CONFIG / "cadip_stac_mapper.json" , encoding = "utf-8" ) as mapper :
145- return link_assets_to_session (session_data , assets , json .loads (mapper .read ()))
161+ # Update input session items with assets
162+ link_assets_to_session (session_features , assets )
163+
164+ def process_files (self , empty_sessions_data : dict ) -> dict :
165+ """
166+ Search cadip files for each input cadip session. Update the sessions data with their files data.
167+
168+ Args:
169+ empty_sessions_data (dict): dict representation of an ItemCollection
170+
171+ Returns:
172+ dict: updated input dict.
173+ """
174+
175+ # Convert input dict into stac object
176+ item_collection = stac_pydantic .ItemCollection .model_validate (empty_sessions_data )
177+
178+ # Group sessions coming from the same collection. {col1: "item1, item2", col2: "item3" }
179+ grouped_sessions = defaultdict (list )
180+ for session in item_collection .features :
181+ grouped_sessions [session .collection ].append (session )
182+
183+ # Update input session assets with their associated files, in separate threads
184+ file_threads = [
185+ threading .Thread (
186+ target = self .process_asset_search ,
187+ args = (
188+ self .select_config (collection_id )["station" ],
189+ session_features ,
190+ ),
191+ )
192+ for collection_id , session_features in grouped_sessions .items ()
193+ ]
194+ for thread in file_threads :
195+ thread .start ()
196+ for thread in file_threads :
197+ thread .join ()
198+
199+ # Convert back the stac object into dict.
200+ # We implemented some custom Item formating, so we do a back and forth conversion
201+ # to apply the formating, then finally return a dict.
202+ formatted = [Item .model_validate (feature .model_dump ()) for feature in item_collection .features ]
203+ return stac_pydantic .ItemCollection (features = formatted , type = item_collection .type ).model_dump ()
146204
147205
148206def auth_validation (request : Request , collection_id : str , access_type : str ):
@@ -455,15 +513,12 @@ def process_session_search( # type: ignore # pylint: disable=too-many-arguments
455513 products = validate_products (products )
456514 feature_template_path = CADIP_CONFIG / "cadip_session_ODataToSTAC_template.json"
457515 stac_mapper_path = CADIP_CONFIG / "cadip_sessions_stac_mapper.json"
458- expanded_session_mapper_path = CADIP_CONFIG / "cadip_stac_mapper.json"
459516 with (
460517 open (feature_template_path , encoding = "utf-8" ) as template ,
461518 open (stac_mapper_path , encoding = "utf-8" ) as stac_map ,
462- open (expanded_session_mapper_path , encoding = "utf-8" ) as expanded_session_mapper ,
463519 ):
464520 feature_template = json .loads (template .read ())
465521 stac_mapper = json .loads (stac_map .read ())
466- expanded_session_mapper = json .loads (expanded_session_mapper .read ())
467522 collection = create_stac_collection (products , feature_template , stac_mapper )
468523 return prepare_collection (collection )
469524
@@ -574,14 +629,9 @@ def process_files_search( # pylint: disable=too-many-locals
574629 if kwargs .get ("deprecated" , False ):
575630 write_search_products_to_db (CadipDownloadStatus , products )
576631 feature_template_path = CADIP_CONFIG / "ODataToSTAC_template.json"
577- stac_mapper_path = CADIP_CONFIG / "cadip_stac_mapper.json"
578- with (
579- open (feature_template_path , encoding = "utf-8" ) as template ,
580- open (stac_mapper_path , encoding = "utf-8" ) as stac_map ,
581- ):
632+ with open (feature_template_path , encoding = "utf-8" ) as template :
582633 feature_template = json .loads (template .read ())
583- stac_mapper = json .loads (stac_map .read ())
584- cadip_item_collection = create_stac_collection (products , feature_template , stac_mapper )
634+ cadip_item_collection = create_stac_collection (products , feature_template , cadip_stac_mapper ())
585635 logger .info ("Succesfully listed and processed products from CADIP station" )
586636 if kwargs .get ("map_to_session" , False ):
587637 return [product .properties for product in products ]
0 commit comments