From dab663813fdbe1779ce3445965845c834b9e02d2 Mon Sep 17 00:00:00 2001 From: hrodmn Date: Fri, 2 Aug 2024 06:58:50 -0500 Subject: [PATCH] apply suggestions from review --- setup.py | 6 +-- stac_fastapi/pgstac/app.py | 2 +- stac_fastapi/pgstac/core.py | 85 ++++++++++++------------------------- 3 files changed, 31 insertions(+), 62 deletions(-) diff --git a/setup.py b/setup.py index fc79debc..456c94fe 100644 --- a/setup.py +++ b/setup.py @@ -10,9 +10,9 @@ "orjson", "pydantic", "stac_pydantic==3.1.*", - "stac-fastapi.api~=3.0.0b3", - "stac-fastapi.extensions~=3.0.0b3", - "stac-fastapi.types~=3.0.0b3", + "stac-fastapi.api~=3.0.0", + "stac-fastapi.extensions~=3.0.0", + "stac-fastapi.types~=3.0.0", "asyncpg", "buildpg", "brotli_asgi", diff --git a/stac_fastapi/pgstac/app.py b/stac_fastapi/pgstac/app.py index f7981980..bde05481 100644 --- a/stac_fastapi/pgstac/app.py +++ b/stac_fastapi/pgstac/app.py @@ -86,7 +86,7 @@ collections_get_request_model = EmptyRequest post_request_model = create_post_request_model(extensions, base_model=PgstacSearch) -get_request_model = create_get_request_model(extensions) +get_request_model = create_get_request_model(extensions + collection_extensions) api = StacApi( settings=settings, diff --git a/stac_fastapi/pgstac/core.py b/stac_fastapi/pgstac/core.py index 214a03fc..4727ac2e 100644 --- a/stac_fastapi/pgstac/core.py +++ b/stac_fastapi/pgstac/core.py @@ -2,7 +2,7 @@ import re from typing import Any, Dict, List, Optional, Set, Union -from urllib.parse import unquote_plus, urljoin +from urllib.parse import unquote_plus import attr import orjson @@ -14,13 +14,14 @@ from pygeofilter.parsers.cql2_text import parse as parse_cql2_text from pypgstac.hydration import hydrate from stac_fastapi.api.models import JSONResponse +from stac_fastapi.extensions.core.collection_search.request import ( + BaseCollectionSearchPostRequest, +) 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.rfc3339 import DateTimeType from stac_fastapi.types.stac import Collection, Collections, Item, ItemCollection -from stac_pydantic.links import Relations -from stac_pydantic.shared import BBox, MimeTypes +from stac_pydantic.shared import BBox from stac_fastapi.pgstac.config import Settings from stac_fastapi.pgstac.models.links import ( @@ -39,13 +40,17 @@ class CoreCrudClient(AsyncBaseCoreClient): """Client for core endpoints defined by stac.""" + collections_post_request_model: BaseCollectionSearchPostRequest = attr.ib( + default=BaseCollectionSearchPostRequest + ) + async def all_collections( # noqa: C901 self, request: Request, + # Extensions bbox: Optional[BBox] = None, datetime: Optional[DateTimeType] = None, limit: Optional[int] = None, - # Extensions query: Optional[str] = None, token: Optional[str] = None, fields: Optional[List[str]] = None, @@ -62,13 +67,6 @@ async def all_collections( # noqa: C901 Collections which match the search criteria, returns all collections by default. """ - query_params = str(request.query_params) - - # Kludgy fix because using factory does not allow alias for filter-lang - if filter_lang is None: - match = re.search(r"filter-lang=([a-z0-9-]+)", query_params, re.IGNORECASE) - if match: - filter_lang = match.group(1) # Parse request parameters base_args = { @@ -89,7 +87,8 @@ async def all_collections( # noqa: C901 # Do the request try: - search_request = self.post_request_model(**clean) + search_request = self.collections_post_request_model(**clean) + # search_request = self.post_request_model(**clean) except ValidationError as e: raise HTTPException( status_code=400, detail=f"Invalid parameters provided {e}" @@ -102,9 +101,9 @@ async def _collection_search_base( # noqa: C901 search_request: PgstacSearch, request: Request, ) -> Collections: - """Cross catalog search (POST). + """Cross catalog search (GET). - Called with `POST /search`. + Called with `GET /search`. Args: search_request: search request parameters. @@ -113,16 +112,6 @@ async def _collection_search_base( # noqa: C901 All collections which match the search criteria. """ - base_url = get_base_url(request) - - settings: Settings = request.app.state.settings - - if search_request.datetime: - search_request.datetime = format_datetime_range(search_request.datetime) - - search_request.conf = search_request.conf or {} - search_request.conf["nohydrate"] = settings.use_api_hydrate - search_request_json = search_request.model_dump_json( exclude_none=True, by_alias=True ) @@ -141,8 +130,12 @@ async def _collection_search_base( # noqa: C901 f"Datetime parameter {search_request.datetime} is invalid." ) from e - # next: Optional[str] = collections_result["links"].pop("next") - # prev: Optional[str] = collections_result["links"].pop("prev") + next: Optional[str] = None + prev: Optional[str] = None + + if links := collections_result.get("links"): + next = collections_result["links"].pop("next") + prev = collections_result["links"].pop("prev") linked_collections: List[Collection] = [] collections = collections_result["collections"] @@ -155,32 +148,15 @@ async def _collection_search_base( # noqa: C901 linked_collections.append(coll) - # paging_links = await PagingLinks( - # request=request, - # next=next, - # prev=prev, - # ).get_links() - - 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"), - }, - ] + links = await PagingLinks( + request=request, + next=next, + prev=prev, + ).get_links() + return Collections( collections=linked_collections or [], - links=links, # + paging_links + links=links, ) async def get_collection( @@ -481,13 +457,6 @@ async def get_search( Returns: ItemCollection containing items which match the search criteria. """ - query_params = str(request.query_params) - - # Kludgy fix because using factory does not allow alias for filter-lang - if filter_lang is None: - match = re.search(r"filter-lang=([a-z0-9-]+)", query_params, re.IGNORECASE) - if match: - filter_lang = match.group(1) # Parse request parameters base_args = {