Skip to content

Commit

Permalink
use enum values and fix fields pydantic validation (#200)
Browse files Browse the repository at this point in the history
* use enum values and fix fields pydantic validation

* revert
  • Loading branch information
vincentsarago authored Feb 18, 2025
1 parent 3f1ffa3 commit a2fb77f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
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

0 comments on commit a2fb77f

Please sign in to comment.