From ab821a5b45784bdc34a0bb1a9950cd14a9be35b7 Mon Sep 17 00:00:00 2001 From: Camille Auriol Date: Thu, 10 Jul 2025 13:29:35 +0200 Subject: [PATCH] feat: pagination token --- stac_fastapi/eodag/app.py | 6 +++--- stac_fastapi/eodag/core.py | 15 +++++---------- stac_fastapi/eodag/models/links.py | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/stac_fastapi/eodag/app.py b/stac_fastapi/eodag/app.py index 6777fb1..c938a12 100644 --- a/stac_fastapi/eodag/app.py +++ b/stac_fastapi/eodag/app.py @@ -45,6 +45,7 @@ SortExtension, ) from stac_fastapi.extensions.core.free_text import FreeTextConformanceClasses +from stac_fastapi.extensions.core.pagination.token_pagination import TokenPaginationExtension from stac_fastapi.extensions.core.query import QueryConformanceClasses from stac_fastapi.extensions.core.sort import SortConformanceClasses @@ -60,7 +61,6 @@ from stac_fastapi.eodag.extensions.ecmwf import EcmwfExtension from stac_fastapi.eodag.extensions.filter import FiltersClient from stac_fastapi.eodag.extensions.offset_pagination import OffsetPaginationExtension -from stac_fastapi.eodag.extensions.pagination import PaginationExtension from stac_fastapi.eodag.extensions.stac import ( ElectroOpticalExtension, FederationExtension, @@ -107,7 +107,7 @@ "query": QueryExtension(), "sort": SortExtension(), "filter": FilterExtension(client=FiltersClient(stac_metadata_model=stac_metadata_model)), - "pagination": PaginationExtension(), + "token": TokenPaginationExtension(), } # collection_search extensions @@ -120,7 +120,7 @@ # item_collection extensions itm_col_extensions_map = { - "pagination": PaginationExtension(), + "token": TokenPaginationExtension(), "sort": SortExtension(conformance_classes=[SortConformanceClasses.ITEMS]), } diff --git a/stac_fastapi/eodag/core.py b/stac_fastapi/eodag/core.py index e436cbb..589274f 100644 --- a/stac_fastapi/eodag/core.py +++ b/stac_fastapi/eodag/core.py @@ -43,7 +43,6 @@ from stac_pydantic.shared import MimeTypes from eodag import SearchResult -from eodag.api.core import DEFAULT_ITEMS_PER_PAGE from eodag.plugins.search.build_search_result import ECMWFSearch from eodag.utils import deepcopy, get_geometry_from_various from eodag.utils.exceptions import NoMatchingProductType as EodagNoMatchingProductType @@ -203,13 +202,8 @@ def _search_base(self, search_request: BaseSearchPostRequest, request: Request) # pagination next_page = None - if search_request.page: - number_returned = len(search_result) - items_per_page = search_request.limit or DEFAULT_ITEMS_PER_PAGE - if not search_result.number_matched or ( - (search_request.page - 1) * items_per_page + number_returned < search_result.number_matched - ): - next_page = search_request.page + 1 + if hasattr(search_result, "next_page_token_key"): + next_page = search_result.next_page_token_key.split(":", 1)[1] collection["links"] = PagingLinks( request=request, @@ -422,6 +416,7 @@ def get_search( intersects: Optional[str] = None, filter_expr: Optional[str] = None, filter_lang: Optional[str] = "cql2-text", + token: Optional[str] = None, **kwargs: Any, ) -> ItemCollection: """ @@ -449,7 +444,7 @@ def get_search( "bbox": bbox, "limit": limit, "query": orjson.loads(unquote_plus(query)) if query else query, - "page": page, + "token": token, "sortby": get_sortby_to_post(sortby), "intersects": orjson.loads(unquote_plus(intersects)) if intersects else intersects, } @@ -544,7 +539,7 @@ def prepare_search_base_args(search_request: BaseSearchPostRequest, model: type[ """ base_args = ( { - "page": search_request.page, + "token": search_request.token, "items_per_page": search_request.limit, "raise_errors": False, "count": get_settings().count, diff --git a/stac_fastapi/eodag/models/links.py b/stac_fastapi/eodag/models/links.py index ded714f..0b36e04 100644 --- a/stac_fastapi/eodag/models/links.py +++ b/stac_fastapi/eodag/models/links.py @@ -146,7 +146,7 @@ def link_next(self) -> Optional[dict[str, Any]]: if self.next is not None: method = self.request.method if method == "GET": - href = merge_params(self.url, {"page": [str(self.next)]}) + href = merge_params(self.url, {"token": [str(self.next)]}) return { "rel": Relations.next.value, "type": MimeTypes.geojson.value,