Skip to content

Commit 15e4b9c

Browse files
committed
first pass
1 parent 8fc2d0d commit 15e4b9c

File tree

2 files changed

+67
-27
lines changed

2 files changed

+67
-27
lines changed

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44
from datetime import datetime as datetime_type
55
from datetime import timezone
66
from typing import Any, Dict, List, Optional, Set, Type, Union
7-
from urllib.parse import urljoin
7+
from base64 import urlsafe_b64encode
88

99
import attr
1010
import stac_pydantic
1111
from fastapi import HTTPException
1212
from overrides import overrides
1313
from pydantic import ValidationError
14+
from starlette.requests import Request
1415
from stac_pydantic.links import Relations
1516
from stac_pydantic.shared import MimeTypes
16-
from starlette.requests import Request
17+
from urllib.parse import urljoin
1718

1819
from stac_fastapi.elasticsearch import serializers
1920
from stac_fastapi.elasticsearch.config import ElasticsearchSettings
@@ -70,7 +71,12 @@ class CoreClient(AsyncBaseCoreClient):
7071
database = DatabaseLogic()
7172

7273
@overrides
73-
async def all_collections(self, **kwargs) -> Collections:
74+
async def all_collections(
75+
self,
76+
limit: Optional[int] = 10,
77+
token: Optional[str] = None,
78+
**kwargs
79+
) -> Collections:
7480
"""Read all collections from the database.
7581
7682
Returns:
@@ -80,30 +86,49 @@ async def all_collections(self, **kwargs) -> Collections:
8086
Raises:
8187
Exception: If any error occurs while reading the collections from the database.
8288
"""
89+
request: Request = kwargs["request"]
8390
base_url = str(kwargs["request"].base_url)
8491

92+
hits = self.database.get_all_collections(limit=limit, token=token)
93+
94+
next_search_after = None
95+
next_link = None
96+
if len(hits) == limit:
97+
last_hit = hits[-1]
98+
next_search_after = last_hit['sort']
99+
next_token = urlsafe_b64encode(','.join(map(str, next_search_after)).encode()).decode()
100+
paging_links = PagingLinks(
101+
next=next_token, request=request
102+
)
103+
next_link = paging_links.link_next()
104+
105+
links=[
106+
{
107+
"rel": Relations.root.value,
108+
"type": MimeTypes.json,
109+
"href": base_url,
110+
},
111+
{
112+
"rel": Relations.parent.value,
113+
"type": MimeTypes.json,
114+
"href": base_url,
115+
},
116+
{
117+
"rel": Relations.self.value,
118+
"type": MimeTypes.json,
119+
"href": urljoin(base_url, "collections"),
120+
}
121+
]
122+
123+
if next_link:
124+
links.append(next_link)
125+
85126
return Collections(
86127
collections=[
87-
self.collection_serializer.db_to_stac(c, base_url=base_url)
88-
for c in await self.database.get_all_collections()
89-
],
90-
links=[
91-
{
92-
"rel": Relations.root.value,
93-
"type": MimeTypes.json,
94-
"href": base_url,
95-
},
96-
{
97-
"rel": Relations.parent.value,
98-
"type": MimeTypes.json,
99-
"href": base_url,
100-
},
101-
{
102-
"rel": Relations.self.value,
103-
"type": MimeTypes.json,
104-
"href": urljoin(base_url, "collections"),
105-
},
128+
self.collection_serializer.db_to_stac(c["_source"], base_url=base_url)
129+
for c in hits
106130
],
131+
links=links
107132
)
108133

109134
@overrides

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/database_logic.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from stac_fastapi.types.errors import ConflictError, NotFoundError
1919
from stac_fastapi.types.stac import Collection, Item
2020

21+
2122
logger = logging.getLogger(__name__)
2223

2324
NumType = Union[float, int]
@@ -295,9 +296,17 @@ class DatabaseLogic:
295296

296297
"""CORE LOGIC"""
297298

298-
async def get_all_collections(self) -> Iterable[Dict[str, Any]]:
299+
async def get_all_collections(
300+
self,
301+
token: Optional[str],
302+
limit: int
303+
) -> Iterable[Dict[str, Any]]:
299304
"""Retrieve a list of all collections from the database.
300305
306+
Args:
307+
token (Optional[str]): The token used to return the next set of results.
308+
limit (int): Number of results to return
309+
301310
Returns:
302311
collections (Iterable[Dict[str, Any]]): A list of dictionaries containing the source data for each collection.
303312
@@ -306,10 +315,16 @@ async def get_all_collections(self) -> Iterable[Dict[str, Any]]:
306315
with the `COLLECTIONS_INDEX` as the target index and `size=1000` to retrieve up to 1000 records.
307316
The result is a generator of dictionaries containing the source data for each collection.
308317
"""
309-
# https://github.com/stac-utils/stac-fastapi-elasticsearch/issues/65
310-
# collections should be paginated, but at least return more than the default 10 for now
311-
collections = await self.client.search(index=COLLECTIONS_INDEX, size=1000)
312-
return (c["_source"] for c in collections["hits"]["hits"])
318+
search_after = None
319+
if token:
320+
search_after = urlsafe_b64decode(token.encode()).decode().split(",")
321+
collections = await self.client.search(
322+
index=COLLECTIONS_INDEX,
323+
search_after=search_after,
324+
size=limit
325+
)
326+
hits = collections["hits"]["hits"]
327+
return hits
313328

314329
async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
315330
"""Retrieve a single item from the database.

0 commit comments

Comments
 (0)