4141from stac_pydantic .links import Relations
4242from stac_pydantic .shared import MimeTypes
4343
44- from eodag import SearchResult
44+ from eodag import EOProduct , SearchResult
4545from eodag .plugins .search .build_search_result import ECMWFSearch
4646from eodag .utils import deepcopy , get_geometry_from_various
4747from eodag .utils .exceptions import NoMatchingCollection as EodagNoMatchingCollection
4848from stac_fastapi .eodag .client import CustomCoreClient
4949from stac_fastapi .eodag .config import get_settings
50+ from stac_fastapi .eodag .constants import DEFAULT_ITEMS_PER_PAGE
5051from stac_fastapi .eodag .cql_evaluate import EodagEvaluator
5152from stac_fastapi .eodag .errors import NoMatchingCollection , ResponseSearchError
5253from stac_fastapi .eodag .models .links import (
@@ -182,15 +183,18 @@ def _search_base(self, search_request: BaseSearchPostRequest, request: Request)
182183 else :
183184 raise HTTPException (status_code = 400 , detail = "A collection is required" )
184185
185- # get products by ids
186186 if ids := eodag_args .pop ("ids" , []):
187+ # get products by ids
187188 search_result = SearchResult ([])
188189 for item_id in ids :
189190 eodag_args ["id" ] = item_id
190191 search_result .extend (request .app .state .dag .search (validate = validate , ** eodag_args ))
191192 search_result .number_matched = len (search_result )
193+ elif eodag_args .get ("token" ) and eodag_args .get ("provider" ):
194+ # search with pagination
195+ search_result = eodag_search_next_page (request .app .state .dag , eodag_args )
192196 else :
193- # search without ids
197+ # search without ids or pagination
194198 search_result = request .app .state .dag .search (validate = validate , ** eodag_args )
195199
196200 if search_result .errors and not len (search_result ):
@@ -207,23 +211,22 @@ def _search_base(self, search_request: BaseSearchPostRequest, request: Request)
207211 )
208212 features .append (feature )
209213
210- collection = ItemCollection (
214+ feature_collection = ItemCollection (
211215 type = "FeatureCollection" ,
212216 features = features ,
213217 numberMatched = search_result .number_matched ,
214218 numberReturned = len (features ),
215219 )
216220
217221 # pagination
218- next_page = None
219- if hasattr (search_result , "next_page_token_key" ):
220- next_page = search_result .next_page_token_key .split (":" , 1 )[1 ]
221-
222- collection ["links" ] = PagingLinks (
222+ if "provider" not in request .state .eodag_args and len (search_result ) > 0 :
223+ request .state .eodag_args ["provider" ] = search_result [- 1 ].provider
224+ feature_collection ["links" ] = PagingLinks (
223225 request = request ,
224- next = next_page ,
226+ next = search_result .next_page_token ,
227+ federation_backend = request .state .eodag_args .get ("provider" ),
225228 ).get_links (request_json = request_json , extensions = extension_names )
226- return collection
229+ return feature_collection
227230
228231 async def all_collections (
229232 self ,
@@ -730,3 +733,36 @@ def add_error(error_message: str) -> None:
730733 raise ValidationError .from_exception_data (title = "stac-fastapi-eodag" , line_errors = errors )
731734
732735 return cql_args
736+
737+
738+ def eodag_search_next_page (dag , eodag_args ):
739+ """Perform an eodag search with pagination.
740+
741+ :param dag: The EODAG instance.
742+ :param eodag_args: The EODAG search arguments.
743+ :returns: The search result for the next page.
744+ """
745+ eodag_args = eodag_args .copy ()
746+ next_page_token = eodag_args .pop ("token" , None )
747+ provider = eodag_args .get ("provider" )
748+ if not next_page_token or not provider :
749+ raise HTTPException (
750+ status_code = 500 , detail = "Missing required token and federation backend for next page search."
751+ )
752+ search_plugin = next (dag ._plugins_manager .get_search_plugins (provider = provider ))
753+ next_page_token_key = getattr (search_plugin .config , "pagination" , {}).get ("next_page_token_key" , "page" )
754+ eodag_args .pop ("count" , None )
755+ search_result = SearchResult (
756+ [EOProduct (provider , {"id" : "_" })] * int (eodag_args .get ("items_per_page" , DEFAULT_ITEMS_PER_PAGE )),
757+ next_page_token = next_page_token ,
758+ next_page_token_key = next_page_token_key ,
759+ search_params = eodag_args ,
760+ raise_errors = eodag_args .pop ("raise_errors" , None ),
761+ )
762+ search_result ._dag = dag
763+ try :
764+ search_result = next (search_result .next_page ())
765+ except StopIteration :
766+ logger .info ("StopIteration encountered during next page search." )
767+ search_result = SearchResult ([])
768+ return search_result
0 commit comments