diff --git a/stac_fastapi/pgstac/core.py b/stac_fastapi/pgstac/core.py index 3d01fb7a..626897a3 100644 --- a/stac_fastapi/pgstac/core.py +++ b/stac_fastapi/pgstac/core.py @@ -150,7 +150,7 @@ async def all_collections( # noqa: C901 prev=prev_link, ).get_links() - return Collections( + collections = Collections( collections=linked_collections or [], links=links, numberMatched=collections_result.get( @@ -161,6 +161,14 @@ async def all_collections( # noqa: C901 ), ) + # 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: + return JSONResponse(collections) # type: ignore + + return collections + async def get_collection( self, collection_id: str, @@ -617,7 +625,7 @@ def _clean_search_args( # noqa: C901 else: includes.add(field) - base_args["fields"] = {"include": includes, "exclude": excludes} + base_args["fields"] = {"include": list(includes), "exclude": list(excludes)} if q: base_args["q"] = q diff --git a/tests/api/test_api.py b/tests/api/test_api.py index 0c9057dc..7aa33d5f 100644 --- a/tests/api/test_api.py +++ b/tests/api/test_api.py @@ -271,6 +271,47 @@ async def test_app_query_extension_gte(load_test_data, app_client, load_test_col assert len(resp_json["features"]) == 1 +async def test_app_collection_fields_extension( + load_test_data, app_client, load_test_collection, app +): + fields = ["title"] + resp = await app_client.get("/collections", params={"fields": ",".join(fields)}) + + assert resp.status_code == 200 + + resp_json = resp.json() + resp_collections = resp_json["collections"] + + assert len(resp_collections) > 0 + # NOTE: It's a bug that 'collection' is always included; see #327 + constant_fields = ["id", "links", "collection"] + for collection in resp_collections: + assert set(collection.keys()) == set(fields + constant_fields) + + +async def test_app_item_fields_extension( + load_test_data, app_client, load_test_collection, load_test_item, app +): + coll = load_test_collection + fields = ["id", "geometry"] + resp = await app_client.get( + f"/collections/{coll['id']}/items", params={"fields": ",".join(fields)} + ) + + assert resp.status_code == 200 + + resp_json = resp.json() + features = resp_json["features"] + + assert len(features) > 0 + # These fields are always included in items + constant_fields = ["id", "links"] + if not app.state.settings.use_api_hydrate: + constant_fields.append("collection") + for item in features: + assert set(item.keys()) == set(fields + constant_fields) + + async def test_app_sort_extension(load_test_data, app_client, load_test_collection): coll = load_test_collection first_item = load_test_data("test_item.json")