Skip to content

Commit a9dce7e

Browse files
authored
handle collection paging differently (#156)
* handle collection paging differently * test next link
1 parent 456c515 commit a9dce7e

File tree

4 files changed

+79
-8
lines changed

4 files changed

+79
-8
lines changed

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ services:
3535
build:
3636
context: .
3737
dockerfile: Dockerfile.tests
38+
volumes:
39+
- .:/app
3840
environment:
3941
- ENVIRONMENT=local
4042
- DB_MIN_CONN_SIZE=1

stac_fastapi/pgstac/core.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from stac_fastapi.pgstac.config import Settings
2626
from stac_fastapi.pgstac.models.links import (
2727
CollectionLinks,
28+
CollectionSearchPagingLinks,
2829
ItemCollectionLinks,
2930
ItemLinks,
3031
PagingLinks,
@@ -90,12 +91,16 @@ async def all_collections( # noqa: C901
9091
)
9192
collections_result: Collections = await conn.fetchval(q, *p)
9293

93-
next: Optional[str] = None
94-
prev: Optional[str] = None
95-
94+
next: Optional[Dict[str, Any]] = None
95+
prev: Optional[Dict[str, Any]] = None
9696
if links := collections_result.get("links"):
97-
next = collections_result["links"].pop("next")
98-
prev = collections_result["links"].pop("prev")
97+
next = None
98+
prev = None
99+
for link in links:
100+
if link["rel"] == "next":
101+
next = link
102+
elif link["rel"] == "prev":
103+
prev = link
99104

100105
linked_collections: List[Collection] = []
101106
collections = collections_result["collections"]
@@ -120,7 +125,7 @@ async def all_collections( # noqa: C901
120125

121126
linked_collections.append(coll)
122127

123-
links = await PagingLinks(
128+
links = await CollectionSearchPagingLinks(
124129
request=request,
125130
next=next,
126131
prev=prev,

stac_fastapi/pgstac/models/links.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,60 @@ def link_prev(self) -> Optional[Dict[str, Any]]:
173173
return None
174174

175175

176+
@attr.s
177+
class CollectionSearchPagingLinks(BaseLinks):
178+
next: Optional[Dict[str, Any]] = attr.ib(kw_only=True, default=None)
179+
prev: Optional[Dict[str, Any]] = attr.ib(kw_only=True, default=None)
180+
181+
def link_next(self) -> Optional[Dict[str, Any]]:
182+
"""Create link for next page."""
183+
if self.next is not None:
184+
method = self.request.method
185+
if method == "GET":
186+
# if offset is equal to default value (0), drop it
187+
if self.next["body"].get("offset", -1) == 0:
188+
_ = self.next["body"].pop("offset")
189+
190+
href = merge_params(self.url, self.next["body"])
191+
192+
# if next link is equal to this link, skip it
193+
if href == self.url:
194+
print(self.request.body())
195+
return None
196+
197+
link = {
198+
"rel": Relations.next.value,
199+
"type": MimeTypes.geojson.value,
200+
"method": method,
201+
"href": href,
202+
}
203+
return link
204+
205+
return None
206+
207+
def link_prev(self):
208+
if self.prev is not None:
209+
method = self.request.method
210+
if method == "GET":
211+
# if offset is equal to default value (0), drop it
212+
if self.prev["body"].get("offset", -1) == 0:
213+
_ = self.prev["body"].pop("offset")
214+
215+
href = merge_params(self.url, self.prev["body"])
216+
217+
# if prev link is equal to this link, skip it
218+
if href == self.url:
219+
return None
220+
return {
221+
"rel": Relations.previous.value,
222+
"type": MimeTypes.geojson.value,
223+
"method": method,
224+
"href": href,
225+
}
226+
227+
return None
228+
229+
176230
@attr.s
177231
class CollectionLinksBase(BaseLinks):
178232
"""Create inferred links specific to collections."""

tests/resources/test_collection.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,15 @@ async def test_get_collections_search_limit_offset(
313313
"/collections",
314314
params={"limit": 1},
315315
)
316-
assert len(resp.json()["collections"]) == 1
317-
assert resp.json()["collections"][0]["id"] == load_test_collection.id
316+
response = resp.json()
317+
assert len(response["collections"]) == 1
318+
assert response["collections"][0]["id"] == load_test_collection["id"]
319+
320+
# check next link
321+
next_link = [link["href"] for link in response["links"] if link["rel"] == "next"][0]
322+
next_url = next_link.replace(str(app_client.base_url), "")
323+
next_resp = await app_client.get(next_url)
324+
next_response = next_resp.json()
325+
326+
assert len(next_response["collections"]) == 1
327+
assert next_response["collections"][0]["id"] == load_test2_collection.id

0 commit comments

Comments
 (0)