11from __future__ import annotations
2+ import json
23import logging
34from pathlib import Path
45from typing import Dict , Any , Optional , Set , List , Tuple
1213from stac_fastapi .pgstac .app import StacApi
1314from stac_fastapi .pgstac .config import Settings
1415from stac_fastapi .pgstac .core import CoreCrudClient
15- from stac_fastapi .pgstac .models .links import ItemLinks , PagingLinks
16+ from stac_fastapi .pgstac .models .links import ItemLinks
1617from stac_fastapi .pgstac .utils import filter_fields
1718from stac_fastapi .types .errors import InvalidQueryParameter
1819from stac_fastapi .types .stac import ItemCollection
@@ -122,17 +123,6 @@ async def _pair_search_base(
122123 raise InvalidQueryParameter (
123124 f"Datetime parameter { search_request .datetime } is invalid."
124125 ) from e
125- # Starting in pgstac 0.9.0, the `next` and `prev` tokens are returned in spec-compliant links with method GET
126- next_from_link : Optional [str ] = None
127- prev_from_link : Optional [str ] = None
128- for link in items .get ("links" , []):
129- if link .get ("rel" ) == "next" :
130- next_from_link = link .get ("href" ).split ("token=next:" )[1 ]
131- if link .get ("rel" ) == "prev" :
132- prev_from_link = link .get ("href" ).split ("token=prev:" )[1 ]
133-
134- next : Optional [str ] = items .pop ("next" , next_from_link )
135- prev : Optional [str ] = items .pop ("prev" , prev_from_link )
136126 collection = ItemCollection (** items )
137127
138128 fields = getattr (search_request , "fields" , None )
@@ -191,13 +181,70 @@ async def _get_base_item(collection_id: str) -> Dict[str, Any]:
191181 cleaned_features .append (feature )
192182
193183 collection ["features" ] = cleaned_features
194- collection [ "links" ] = await PagingLinks (
195- request = request ,
196- next = next ,
197- prev = prev ,
198- ). get_links ()
184+ if cleaned_features :
185+ collection [ "links" ] = await self . _get_search_links (
186+ search_request = search_request , request = request
187+ )
188+
199189 return collection
200190
191+ async def _get_search_links (
192+ self , search_request : PairSearchRequest , request : Request
193+ ) -> List [Dict [str , str ]]:
194+ """Take existing request and edit offset."""
195+ links = []
196+ next_page_offset = search_request .offset + search_request .limit
197+ prev_page_offset = max (search_request .offset - search_request .limit , 0 )
198+ if request .method == "GET" :
199+ query_params = request .query_params .multi_items ()
200+ links .append (
201+ {
202+ "rel" : "next" ,
203+ "href" : request .url .replace_query_params (
204+ ** dict (query_params , offset = next_page_offset )
205+ ),
206+ "type" : "application/geo+json" ,
207+ }
208+ )
209+ # add link to previous page
210+ if search_request .offset :
211+ links .append (
212+ {
213+ "rel" : "prev" ,
214+ "href" : request .url .replace_query_params (
215+ ** dict (
216+ query_params ,
217+ offset = prev_page_offset ,
218+ )
219+ ),
220+ "type" : "application/geo+json" ,
221+ }
222+ )
223+ elif request .method == "POST" :
224+ body = await request .body ()
225+ links .append (
226+ {
227+ "rel" : "next" ,
228+ "href" : request .url ,
229+ "type" : "application/geo+json" ,
230+ "method" : "POST" ,
231+ "body" : dict (json .loads (body ), offset = next_page_offset ),
232+ }
233+ )
234+ # add link to previous page
235+ if search_request .offset :
236+ links .append (
237+ {
238+ "rel" : "prev" ,
239+ "href" : request .url ,
240+ "type" : "application/geo+json" ,
241+ "method" : "POST" ,
242+ "body" : dict (json .loads (body ), offset = prev_page_offset ),
243+ }
244+ )
245+
246+ return links
247+
201248
202249def render_sql (pair_search_request : PairSearchRequest ) -> Tuple [str , List [Any ]]:
203250 filter_query , filter_params = pair_search_request .filter_sql
@@ -212,6 +259,7 @@ def render_sql(pair_search_request: PairSearchRequest) -> Tuple[str, List[Any]]:
212259 exclude_none = True , by_alias = True
213260 ),
214261 limit = pair_search_request .limit or 10 ,
262+ offset = pair_search_request .offset or 0 ,
215263 response_type = pair_search_request .response_type ,
216264 ** filter_params ,
217265 )
0 commit comments