Skip to content

Commit a2fb77f

Browse files
use enum values and fix fields pydantic validation (#200)
* use enum values and fix fields pydantic validation * revert
1 parent 3f1ffa3 commit a2fb77f

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

CHANGES.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
## [Unreleased]
44

5+
### Fixed
6+
7+
- use Relation's `value` for `POST` prev/next links
8+
- return `JSONResponse` directly from `/items` endpoint when `fields` parameter is pass and avoid Pydantic validation
9+
10+
### Changed
11+
12+
- avoid re-use of internal `CoreCrudClient.post_search` in `CoreCrudClient.get_search` method to allow customization
13+
514
## [4.0.1] - 2025-02-06
615

716
### Added

stac_fastapi/pgstac/core.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,15 +393,28 @@ async def item_collection(
393393
sortby=sortby,
394394
)
395395

396-
search_request = self.pgstac_search_model(**clean)
396+
try:
397+
search_request = self.pgstac_search_model(**clean)
398+
except ValidationError as e:
399+
raise HTTPException(
400+
status_code=400, detail=f"Invalid parameters provided {e}"
401+
) from e
402+
397403
item_collection = await self._search_base(search_request, request=request)
398404

399405
links = await ItemCollectionLinks(
400406
collection_id=collection_id, request=request
401407
).get_links(extra_links=item_collection["links"])
402408
item_collection["links"] = links
403409

404-
return item_collection
410+
# If we have the `fields` extension enabled
411+
# we need to avoid Pydantic validation because the
412+
# Items might not be a valid STAC Item objects
413+
if fields := getattr(search_request, "fields", None):
414+
if fields.include or fields.exclude:
415+
return JSONResponse(item_collection) # type: ignore
416+
417+
return ItemCollection(**item_collection)
405418

406419
async def get_item(
407420
self, item_id: str, collection_id: str, request: Request, **kwargs
@@ -500,15 +513,23 @@ async def get_search(
500513
filter_lang=filter_lang,
501514
)
502515

503-
# Do the request
504516
try:
505517
search_request = self.pgstac_search_model(**clean)
506518
except ValidationError as e:
507519
raise HTTPException(
508520
status_code=400, detail=f"Invalid parameters provided {e}"
509521
) from e
510522

511-
return await self.post_search(search_request, request=request)
523+
item_collection = await self._search_base(search_request, request=request)
524+
525+
# If we have the `fields` extension enabled
526+
# we need to avoid Pydantic validation because the
527+
# Items might not be a valid STAC Item objects
528+
if fields := getattr(search_request, "fields", None):
529+
if fields.include or fields.exclude:
530+
return JSONResponse(item_collection) # type: ignore
531+
532+
return ItemCollection(**item_collection)
512533

513534
def _clean_search_args( # noqa: C901
514535
self,

stac_fastapi/pgstac/models/links.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ def link_next(self) -> Optional[Dict[str, Any]]:
140140

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

165165
if method == "POST":
166166
return {
167-
"rel": Relations.previous,
168-
"type": MimeTypes.geojson,
167+
"rel": Relations.previous.value,
168+
"type": MimeTypes.geojson.value,
169169
"method": method,
170170
"href": f"{self.request.url}",
171171
"body": {**self.request.postbody, "token": f"prev:{self.prev}"},

tests/resources/test_item.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,13 @@ async def test_field_extension_get(app_client, load_test_data, load_test_collect
10721072
)
10731073
assert resp.status_code == 201
10741074

1075+
params = {"fields": "+properties.proj:epsg,+properties.gsd,+collection"}
1076+
resp = await app_client.get(
1077+
f"/collections/{test_item['collection']}/items", params=params
1078+
)
1079+
feat_properties = resp.json()["features"][0]["properties"]
1080+
assert not set(feat_properties) - {"proj:epsg", "gsd", "datetime"}
1081+
10751082
params = {"fields": "+properties.proj:epsg,+properties.gsd,+collection"}
10761083
resp = await app_client.get("/search", params=params)
10771084
feat_properties = resp.json()["features"][0]["properties"]

0 commit comments

Comments
 (0)