Skip to content
Open
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ For more than millions of records it is recommended to either set a low connecti

### Hydration

To configure **stac-fastapi-pgstac** to [hydrate search result items in the API](https://stac-utils.github.io/pgstac/pgstac/#runtime-configurations), set the `USE_API_HYDRATE` environment variable to `true` or explicitly set the option in the PGStac Settings object.
To configure **stac-fastapi-pgstac** to [hydrate search result items at the API level](https://stac-utils.github.io/pgstac/pgstac/#runtime-configurations), set the `USE_API_HYDRATE` environment variable to `true`. If `false` (default) the hydration will be done in the database.

| use_api_hydrate (API) | nohydrate (PgSTAC) | Hydration |
| --- | --- | --- |
| False | False | PgSTAC |
| True | True | API |

### Migrations

Expand Down
10 changes: 10 additions & 0 deletions stac_fastapi/pgstac/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ class Settings(ApiSettings):

prefix_path: str = ""
use_api_hydrate: bool = False
"""
When USE_API_HYDRATE=TRUE, PgSTAC database will receive `NO_HYDRATE=TRUE`

| use_api_hydrate | nohydrate | Hydration |
| --- | --- | --- |
| False | False | PgSTAC |
| True | True | API |

ref: https://stac-utils.github.io/pgstac/pgstac/#runtime-configurations
"""
invalid_id_chars: List[str] = DEFAULT_INVALID_ID_CHARS
base_item_cache: Type[BaseItemCache] = DefaultBaseItemCache

Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,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, model_validation
# API hydratation, prefix, model_validation
(False, "", False),
(False, "/router_prefix", False),
(True, "", False),
Expand Down
3 changes: 1 addition & 2 deletions tests/data/test2_item.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"nodata": 0,
"offset": 2.03976,
"data_type": "uint8",
"spatial_resolution": 60
"spatial_resolution": 80
}
]
},
Expand Down Expand Up @@ -172,7 +172,6 @@
"type": "image/tiff; application=geotiff; profile=cloud-optimized",
"roles": ["cloud"],
"title": "Pixel Quality Assessment Band (QA_PIXEL)",
"description": "Collection 2 Level-1 Pixel Quality Assessment Band",
"raster:bands": [
{
"unit": "bit index",
Expand Down
68 changes: 68 additions & 0 deletions tests/resources/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -1722,3 +1722,71 @@ async def test_item_search_freetext(app_client, load_test_data, load_test_collec
params={"q": "yo"},
)
assert resp.json()["numberReturned"] == 0


@pytest.mark.asyncio
async def test_item_asset_change(app_client, load_test_data):
"""Check that changing item_assets in collection does
not affect existing items if hydration should not occur.

"""
# load collection
data = load_test_data("test2_collection.json")
collection_id = data["id"]

resp = await app_client.post("/collections", json=data)
assert "item_assets" in data
assert resp.status_code == 201
assert "item_assets" in resp.json()

# load items
test_item = load_test_data("test2_item.json")
resp = await app_client.post(f"/collections/{collection_id}/items", json=test_item)
assert resp.status_code == 201

# check list of items
resp = await app_client.get(
f"/collections/{collection_id}/items", params={"limit": 1}
)
assert len(resp.json()["features"]) == 1
assert resp.status_code == 200

# NOTE: API or PgSTAC Hydration we should get the same values as original Item
assert (
test_item["assets"]["red"]["raster:bands"]
== resp.json()["features"][0]["assets"]["red"]["raster:bands"]
)

# NOTE: `description` is not in the item body but in the collection's item-assets
# because it's not in the original item it won't be hydrated
assert not resp.json()["features"][0]["assets"]["qa_pixel"].get("description")

###########################################################################
# Remove item_assets in collection
operations = [{"op": "remove", "path": "/item_assets"}]
resp = await app_client.patch(f"/collections/{collection_id}", json=operations)
assert resp.status_code == 200

# Make sure item_assets is not in collection response
resp = await app_client.get(f"/collections/{collection_id}")
assert resp.status_code == 200
assert "item_assets" not in resp.json()
###########################################################################

resp = await app_client.get(
f"/collections/{collection_id}/items", params={"limit": 1}
)
assert len(resp.json()["features"]) == 1
assert resp.status_code == 200

# NOTE: here we should only get `scale`, `offset` and `spatial_resolution`
# because the other values were stripped on ingestion (dehydration is a default in PgSTAC)
# scale and offset are no in item-asset and spatial_resolution is different, so the value in the item body is kept
assert ["scale", "offset", "spatial_resolution"] == list(
resp.json()["features"][0]["assets"]["red"]["raster:bands"][0]
)

# NOTE: `description` is not in the original item but in the collection's item-assets
# We get "𒍟※" because PgSTAC set it when ingesting (`description`is item-assets)
# because we removed item-assets, pgstac cannot hydrate this field, and thus return "𒍟※"
assert resp.json()["features"][0]["assets"]["qa_pixel"]["description"] == "𒍟※"
Loading