Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## [Unreleased]

### Fixed

- use Relation's `value` for `POST` prev/next links
- return `JSONResponse` directly from `/items` endpoint when `fields` parameter is pass and avoid Pydantic validation

### Changed

- avoid re-use of internal `CoreCrudClient.post_search` in `CoreCrudClient.get_search` method to allow customization

## [4.0.1] - 2025-02-06

### Added
Expand Down
29 changes: 25 additions & 4 deletions stac_fastapi/pgstac/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,28 @@ async def item_collection(
sortby=sortby,
)

search_request = self.pgstac_search_model(**clean)
try:
search_request = self.pgstac_search_model(**clean)
except ValidationError as e:
raise HTTPException(
status_code=400, detail=f"Invalid parameters provided {e}"
) from e

item_collection = await self._search_base(search_request, request=request)

links = await ItemCollectionLinks(
collection_id=collection_id, request=request
).get_links(extra_links=item_collection["links"])
item_collection["links"] = links

return item_collection
# 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_item(
self, item_id: str, collection_id: str, request: Request, **kwargs
Expand Down Expand Up @@ -500,15 +513,23 @@ async def get_search(
filter_lang=filter_lang,
)

# Do the request
try:
search_request = self.pgstac_search_model(**clean)
except ValidationError as e:
raise HTTPException(
status_code=400, detail=f"Invalid parameters provided {e}"
) from e

return await self.post_search(search_request, request=request)
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)

def _clean_search_args( # noqa: C901
self,
Expand Down
8 changes: 4 additions & 4 deletions stac_fastapi/pgstac/models/links.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ def link_next(self) -> Optional[Dict[str, Any]]:

if method == "POST":
return {
"rel": Relations.next,
"type": MimeTypes.geojson,
"rel": Relations.next.value,
"type": MimeTypes.geojson.value,
"method": method,
"href": f"{self.request.url}",
"body": {**self.request.postbody, "token": f"next:{self.next}"},
Expand All @@ -164,8 +164,8 @@ def link_prev(self) -> Optional[Dict[str, Any]]:

if method == "POST":
return {
"rel": Relations.previous,
"type": MimeTypes.geojson,
"rel": Relations.previous.value,
"type": MimeTypes.geojson.value,
"method": method,
"href": f"{self.request.url}",
"body": {**self.request.postbody, "token": f"prev:{self.prev}"},
Expand Down
7 changes: 7 additions & 0 deletions tests/resources/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,13 @@ async def test_field_extension_get(app_client, load_test_data, load_test_collect
)
assert resp.status_code == 201

params = {"fields": "+properties.proj:epsg,+properties.gsd,+collection"}
resp = await app_client.get(
f"/collections/{test_item['collection']}/items", params=params
)
feat_properties = resp.json()["features"][0]["properties"]
assert not set(feat_properties) - {"proj:epsg", "gsd", "datetime"}

params = {"fields": "+properties.proj:epsg,+properties.gsd,+collection"}
resp = await app_client.get("/search", params=params)
feat_properties = resp.json()["features"][0]["properties"]
Expand Down
Loading