diff --git a/CHANGES.md b/CHANGES.md index 5b31a38..8348aa6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ## [Unreleased] +## [3.0.0a4] - 2024-07-10 + +- Update stac-fastapi libraries to `~=3.0.0b2` + ## [3.0.0a3] - 2024-07-01 - Use `quote_plus` instead of `quote` to encode database's password ([#122](https://github.com/stac-utils/stac-fastapi-pgstac/pull/122)) diff --git a/setup.py b/setup.py index 384ffd1..585737d 100644 --- a/setup.py +++ b/setup.py @@ -10,9 +10,9 @@ "orjson", "pydantic", "stac_pydantic==3.1.*", - "stac-fastapi.api~=3.0.0a4", - "stac-fastapi.extensions~=3.0.0a4", - "stac-fastapi.types~=3.0.0a4", + "stac-fastapi.api~=3.0.0b2", + "stac-fastapi.extensions~=3.0.0b2", + "stac-fastapi.types~=3.0.0b2", "asyncpg", "buildpg", "brotli_asgi", diff --git a/stac_fastapi/pgstac/app.py b/stac_fastapi/pgstac/app.py index 067a244..924ea01 100644 --- a/stac_fastapi/pgstac/app.py +++ b/stac_fastapi/pgstac/app.py @@ -9,7 +9,12 @@ from fastapi.responses import ORJSONResponse from stac_fastapi.api.app import StacApi -from stac_fastapi.api.models import create_get_request_model, create_post_request_model +from stac_fastapi.api.models import ( + ItemCollectionUri, + create_get_request_model, + create_post_request_model, + create_request_model, +) from stac_fastapi.extensions.core import ( FieldsExtension, FilterExtension, @@ -49,13 +54,25 @@ else: extensions = list(extensions_map.values()) +if any(isinstance(ext, TokenPaginationExtension) for ext in extensions): + items_get_request_model = create_request_model( + model_name="ItemCollectionUri", + base_model=ItemCollectionUri, + mixins=[TokenPaginationExtension().GET], + request_type="GET", + ) +else: + items_get_request_model = ItemCollectionUri + post_request_model = create_post_request_model(extensions, base_model=PgstacSearch) get_request_model = create_get_request_model(extensions) + api = StacApi( settings=settings, extensions=extensions, client=CoreCrudClient(post_request_model=post_request_model), # type: ignore response_class=ORJSONResponse, + items_get_request_model=items_get_request_model, search_get_request_model=get_request_model, search_post_request_model=post_request_model, ) diff --git a/stac_fastapi/pgstac/core.py b/stac_fastapi/pgstac/core.py index 3bc0dce..63e2182 100644 --- a/stac_fastapi/pgstac/core.py +++ b/stac_fastapi/pgstac/core.py @@ -13,6 +13,7 @@ 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_fastapi.api.models import JSONResponse from stac_fastapi.types.core import AsyncBaseCoreClient from stac_fastapi.types.errors import InvalidQueryParameter, NotFoundError from stac_fastapi.types.requests import get_base_url @@ -341,6 +342,14 @@ async def post_search( ItemCollection containing items which match the search criteria. """ item_collection = await self._search_base(search_request, request=request) + + # If we have the `fields` extension enabled + # we need to avoid Pydantic validation because the + # Items might not be a valid STAC Item objects + if fields := getattr(search_request, "fields", None): + if fields.include or fields.exclude: + return JSONResponse(item_collection) # type: ignore + return ItemCollection(**item_collection) async def get_search( # noqa: C901 diff --git a/tests/conftest.py b/tests/conftest.py index edb916b..6740026 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,7 +16,12 @@ from pypgstac.migrate import Migrate from pytest_postgresql.janitor import DatabaseJanitor from stac_fastapi.api.app import StacApi -from stac_fastapi.api.models import create_get_request_model, create_post_request_model +from stac_fastapi.api.models import ( + ItemCollectionUri, + create_get_request_model, + create_post_request_model, + create_request_model, +) from stac_fastapi.extensions.core import ( FieldsExtension, FilterExtension, @@ -86,7 +91,7 @@ async def pgstac(database): # Run all the tests that use the api_client in both db hydrate and api hydrate mode @pytest.fixture( params=[ - # hydratation, prefix + # hydratation, prefix, model_validation (False, "", False), (False, "/router_prefix", False), (True, "", False), @@ -129,13 +134,23 @@ def api_client(request, database): BulkTransactionExtension(client=BulkTransactionsClient()), ] - post_request_model = create_post_request_model(extensions, base_model=PgstacSearch) + items_get_request_model = create_request_model( + model_name="ItemCollectionUri", + base_model=ItemCollectionUri, + mixins=[TokenPaginationExtension().GET], + request_type="GET", + ) + search_get_request_model = create_get_request_model(extensions) + search_post_request_model = create_post_request_model( + extensions, base_model=PgstacSearch + ) api = StacApi( settings=api_settings, extensions=extensions, - client=CoreCrudClient(post_request_model=post_request_model), - search_get_request_model=create_get_request_model(extensions), - search_post_request_model=post_request_model, + client=CoreCrudClient(post_request_model=search_post_request_model), + items_get_request_model=items_get_request_model, + search_get_request_model=search_get_request_model, + search_post_request_model=search_post_request_model, response_class=ORJSONResponse, router=APIRouter(prefix=prefix), )