77from urllib .parse import urljoin
88
99import attr
10- import stac_pydantic .api
1110from fastapi import HTTPException
1211from overrides import overrides
1312from pydantic import ValidationError
2120from stac_fastapi .elasticsearch .models .links import PagingLinks
2221from stac_fastapi .elasticsearch .serializers import CollectionSerializer , ItemSerializer
2322from stac_fastapi .elasticsearch .session import Session
24- from stac_fastapi .extensions .core .filter .request import FilterLang
2523from stac_fastapi .extensions .third_party .bulk_transactions import (
2624 BaseBulkTransactionsClient ,
2725 Items ,
3331 AsyncBaseTransactionsClient ,
3432)
3533from stac_fastapi .types .links import CollectionLinks
34+ from stac_fastapi .types .search import BaseSearchPostRequest
3635from stac_fastapi .types .stac import Collection , Collections , Item , ItemCollection
3736
3837logger = logging .getLogger (__name__ )
@@ -91,21 +90,49 @@ async def get_collection(self, collection_id: str, **kwargs) -> Collection:
9190
9291 @overrides
9392 async def item_collection (
94- self , collection_id : str , limit : int = 10 , token : str = None , ** kwargs
93+ self ,
94+ collection_id : str ,
95+ bbox : Optional [List [NumType ]] = None ,
96+ datetime : Union [str , datetime_type , None ] = None ,
97+ limit : int = 10 ,
98+ token : str = None ,
99+ ** kwargs ,
95100 ) -> ItemCollection :
96101 """Read an item collection from the database."""
97102 request : Request = kwargs ["request" ]
98- base_url = str (kwargs ["request" ].base_url )
103+ base_url = str (request .base_url )
104+
105+ collection = await self .get_collection (
106+ collection_id = collection_id , request = request
107+ )
108+ collection_id = collection .get ("id" )
109+ if collection_id is None :
110+ raise HTTPException (status_code = 404 , detail = "Collection not found" )
111+
112+ search = self .database .make_search ()
113+ search = self .database .apply_collections_filter (
114+ search = search , collection_ids = [collection_id ]
115+ )
116+
117+ if datetime :
118+ datetime_search = self ._return_date (datetime )
119+ search = self .database .apply_datetime_filter (
120+ search = search , datetime_search = datetime_search
121+ )
122+
123+ if bbox :
124+ bbox = [float (x ) for x in bbox ]
125+ if len (bbox ) == 6 :
126+ bbox = [bbox [0 ], bbox [1 ], bbox [3 ], bbox [4 ]]
127+
128+ search = self .database .apply_bbox_filter (search = search , bbox = bbox )
99129
100130 items , maybe_count , next_token = await self .database .execute_search (
101- search = self .database .apply_collections_filter (
102- self .database .make_search (), [collection_id ]
103- ),
131+ search = search ,
104132 limit = limit ,
105- token = token ,
106133 sort = None ,
134+ token = token , # type: ignore
107135 collection_ids = [collection_id ],
108- ignore_unavailable = False ,
109136 )
110137
111138 items = [
@@ -236,7 +263,7 @@ async def get_search(
236263
237264 @overrides
238265 async def post_search (
239- self , search_request : stac_pydantic . api . Search , ** kwargs
266+ self , search_request : BaseSearchPostRequest , ** kwargs
240267 ) -> ItemCollection :
241268 """POST search catalog."""
242269 request : Request = kwargs ["request" ]
@@ -280,14 +307,15 @@ async def post_search(
280307 search = search , op = op , field = field , value = value
281308 )
282309
283- filter_lang = getattr (search_request , "filter_lang" , None )
284-
310+ # only cql2_json is supported here
285311 if hasattr (search_request , "filter" ):
286312 cql2_filter = getattr (search_request , "filter" , None )
287- if filter_lang in [ None , FilterLang . cql2_json ] :
313+ try :
288314 search = self .database .apply_cql2_filter (search , cql2_filter )
289- else :
290- raise Exception ("CQL2-Text is not supported with POST" )
315+ except Exception as e :
316+ raise HTTPException (
317+ status_code = 400 , detail = f"Error with cql2_json filter: { e } "
318+ )
291319
292320 sort = None
293321 if search_request .sortby :
@@ -358,7 +386,9 @@ class TransactionsClient(AsyncBaseTransactionsClient):
358386 database = DatabaseLogic ()
359387
360388 @overrides
361- async def create_item (self , item : stac_types .Item , ** kwargs ) -> stac_types .Item :
389+ async def create_item (
390+ self , collection_id : str , item : stac_types .Item , ** kwargs
391+ ) -> stac_types .Item :
362392 """Create item."""
363393 base_url = str (kwargs ["request" ].base_url )
364394
@@ -369,8 +399,6 @@ async def create_item(self, item: stac_types.Item, **kwargs) -> stac_types.Item:
369399 bulk_client .preprocess_item (item , base_url ) for item in item ["features" ] # type: ignore
370400 ]
371401
372- # not a great way to get the collection_id-- should be part of the method signature
373- collection_id = processed_items [0 ]["collection" ]
374402 await self .database .bulk_async (
375403 collection_id , processed_items , refresh = kwargs .get ("refresh" , False )
376404 )
@@ -382,18 +410,19 @@ async def create_item(self, item: stac_types.Item, **kwargs) -> stac_types.Item:
382410 return item
383411
384412 @overrides
385- async def update_item (self , item : stac_types .Item , ** kwargs ) -> stac_types .Item :
413+ async def update_item (
414+ self , collection_id : str , item_id : str , item : stac_types .Item , ** kwargs
415+ ) -> stac_types .Item :
386416 """Update item."""
387417 base_url = str (kwargs ["request" ].base_url )
388- collection_id = item ["collection" ]
389418
390419 now = datetime_type .now (timezone .utc ).isoformat ().replace ("+00:00" , "Z" )
391420 item ["properties" ]["updated" ] = str (now )
392421
393422 await self .database .check_collection_exists (collection_id )
394423 # todo: index instead of delete and create
395- await self .delete_item (item_id = item [ "id" ] , collection_id = collection_id )
396- await self .create_item (item = item , ** kwargs )
424+ await self .delete_item (item_id = item_id , collection_id = collection_id )
425+ await self .create_item (collection_id = collection_id , item = item , ** kwargs )
397426
398427 return ItemSerializer .db_to_stac (item , base_url )
399428
0 commit comments