diff --git a/setup.py b/setup.py index 86f25d7b..18c68f00 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ "orjson", "pydantic[dotenv]", "stac_pydantic==2.0.*", - "stac-fastapi @ git+https://github.com/stac-utils/stac-fastapi.git@2d72c588151fc16eec1564553a653a039bce6c58", + "stac-fastapi @ git+https://github.com/stac-utils/stac-fastapi.git@c4b738ea3bf8f50473db35b7b505edf1a46d2b06", "asyncpg", "buildpg", "brotli_asgi", diff --git a/stac_fastapi/pgstac/core.py b/stac_fastapi/pgstac/core.py index 07844f4b..11eab1d7 100644 --- a/stac_fastapi/pgstac/core.py +++ b/stac_fastapi/pgstac/core.py @@ -2,7 +2,6 @@ import re from datetime import datetime from typing import Any, Dict, List, Optional, Union -from urllib.parse import urljoin import attr import orjson @@ -13,8 +12,6 @@ from pygeofilter.backends.cql2_json import to_cql2 from pygeofilter.parsers.cql2_text import parse as parse_cql2_text from pypgstac.hydration import hydrate -from stac_pydantic.links import Relations -from stac_pydantic.shared import MimeTypes from starlette.requests import Request from stac_fastapi.pgstac.config import Settings @@ -23,7 +20,6 @@ from stac_fastapi.pgstac.utils import filter_fields from stac_fastapi.types.core import AsyncBaseCoreClient from stac_fastapi.types.errors import InvalidQueryParameter, NotFoundError -from stac_fastapi.types.requests import get_base_url from stac_fastapi.types.stac import Collection, Collections, Item, ItemCollection NumType = Union[float, int] @@ -33,49 +29,20 @@ class CoreCrudClient(AsyncBaseCoreClient): """Client for core endpoints defined by stac.""" - async def all_collections(self, **kwargs) -> Collections: + async def fetch_all_collections(self, request: Request) -> Collections: """Read all collections from the database.""" - request: Request = kwargs["request"] - base_url = get_base_url(request) pool = request.app.state.readpool async with pool.acquire() as conn: - collections = await conn.fetchval( + return await conn.fetchval( """ SELECT * FROM all_collections(); """ ) - linked_collections: List[Collection] = [] - if collections is not None and len(collections) > 0: - for c in collections: - coll = Collection(**c) - coll["links"] = await CollectionLinks( - collection_id=coll["id"], request=request - ).get_links(extra_links=coll.get("links")) - - linked_collections.append(coll) - - links = [ - { - "rel": Relations.root.value, - "type": MimeTypes.json, - "href": base_url, - }, - { - "rel": Relations.parent.value, - "type": MimeTypes.json, - "href": base_url, - }, - { - "rel": Relations.self.value, - "type": MimeTypes.json, - "href": urljoin(base_url, "collections"), - }, - ] - collection_list = Collections(collections=linked_collections or [], links=links) - return collection_list - - async def get_collection(self, collection_id: str, **kwargs) -> Collection: + + async def fetch_collection( + self, collection_id: str, request: Request + ) -> Collection: """Get collection by id. Called with `GET /collections/{collection_id}`. @@ -86,9 +53,6 @@ async def get_collection(self, collection_id: str, **kwargs) -> Collection: Returns: Collection. """ - collection: Optional[Dict[str, Any]] - - request: Request = kwargs["request"] pool = request.app.state.readpool async with pool.acquire() as conn: q, p = render( @@ -97,15 +61,7 @@ async def get_collection(self, collection_id: str, **kwargs) -> Collection: """, id=collection_id, ) - collection = await conn.fetchval(q, *p) - if collection is None: - raise NotFoundError(f"Collection {collection_id} does not exist.") - - collection["links"] = await CollectionLinks( - collection_id=collection_id, request=request - ).get_links(extra_links=collection.get("links")) - - return Collection(**collection) + return await conn.fetchval(q, *p) async def _get_base_item( self, collection_id: str, request: Request @@ -245,7 +201,7 @@ async def _get_base_item(collection_id: str) -> Dict[str, Any]: ).get_links() return collection - async def item_collection( + async def handle_collection_items( self, collection_id: str, limit: Optional[int] = None, @@ -265,7 +221,7 @@ async def item_collection( An ItemCollection. """ # If collection does not exist, NotFoundError wil be raised - await self.get_collection(collection_id, **kwargs) + await self.handle_get_collection(collection_id, **kwargs) req = self.post_request_model( collections=[collection_id], limit=limit, token=token @@ -277,7 +233,7 @@ async def item_collection( item_collection["links"] = links return item_collection - async def get_item(self, item_id: str, collection_id: str, **kwargs) -> Item: + async def handle_get_item(self, item_id: str, collection_id: str, **kwargs) -> Item: """Get item by id. Called with `GET /collections/{collection_id}/items/{item_id}`. @@ -290,7 +246,7 @@ async def get_item(self, item_id: str, collection_id: str, **kwargs) -> Item: Item. """ # If collection does not exist, NotFoundError wil be raised - await self.get_collection(collection_id, **kwargs) + await self.handle_get_collection(collection_id, **kwargs) req = self.post_request_model( ids=[item_id], collections=[collection_id], limit=1 @@ -303,7 +259,7 @@ async def get_item(self, item_id: str, collection_id: str, **kwargs) -> Item: return Item(**item_collection["features"][0]) - async def post_search( + async def handle_post_search( self, search_request: PgstacSearch, **kwargs ) -> ItemCollection: """Cross catalog search (POST). @@ -319,7 +275,7 @@ async def post_search( item_collection = await self._search_base(search_request, **kwargs) return ItemCollection(**item_collection) - async def get_search( + async def handle_get_search( self, collections: Optional[List[str]] = None, ids: Optional[List[str]] = None, @@ -408,4 +364,4 @@ async def get_search( raise HTTPException( status_code=400, detail=f"Invalid parameters provided {e}" ) - return await self.post_search(search_request, request=kwargs["request"]) + return await self.handle_post_search(search_request, request=kwargs["request"]) diff --git a/stac_fastapi/pgstac/transactions.py b/stac_fastapi/pgstac/transactions.py index 9013a631..840e9db2 100644 --- a/stac_fastapi/pgstac/transactions.py +++ b/stac_fastapi/pgstac/transactions.py @@ -24,7 +24,7 @@ class TransactionsClient(AsyncBaseTransactionsClient): """Transactions extension specific CRUD operations.""" - async def create_item( + async def handle_create_item( self, collection_id: str, item: stac_types.Item, **kwargs ) -> Optional[Union[stac_types.Item, Response]]: """Create item.""" @@ -45,7 +45,7 @@ async def create_item( ).get_links(extra_links=item.get("links")) return stac_types.Item(**item) - async def update_item( + async def handle_update_item( self, collection_id: str, item_id: str, item: stac_types.Item, **kwargs ) -> Optional[Union[stac_types.Item, Response]]: """Update item.""" @@ -72,7 +72,7 @@ async def update_item( ).get_links(extra_links=item.get("links")) return stac_types.Item(**item) - async def create_collection( + async def handle_create_collection( self, collection: stac_types.Collection, **kwargs ) -> Optional[Union[stac_types.Collection, Response]]: """Create collection.""" @@ -85,7 +85,7 @@ async def create_collection( return stac_types.Collection(**collection) - async def update_collection( + async def handle_update_collection( self, collection: stac_types.Collection, **kwargs ) -> Optional[Union[stac_types.Collection, Response]]: """Update collection.""" @@ -97,7 +97,7 @@ async def update_collection( ).get_links(extra_links=collection.get("links")) return stac_types.Collection(**collection) - async def delete_item( + async def handle_delete_item( self, item_id: str, **kwargs ) -> Optional[Union[stac_types.Item, Response]]: """Delete item.""" @@ -106,7 +106,7 @@ async def delete_item( await dbfunc(pool, "delete_item", item_id) return JSONResponse({"deleted item": item_id}) - async def delete_collection( + async def handle_delete_collection( self, collection_id: str, **kwargs ) -> Optional[Union[stac_types.Collection, Response]]: """Delete collection.""" @@ -120,7 +120,7 @@ async def delete_collection( class BulkTransactionsClient(AsyncBaseBulkTransactionsClient): """Postgres bulk transactions.""" - async def bulk_item_insert(self, items: Items, **kwargs) -> str: + async def handle_bulk_item_insert(self, items: Items, **kwargs) -> str: """Bulk item insertion using pgstac.""" request = kwargs["request"] pool = request.app.state.writepool