Skip to content

Commit a2280a9

Browse files
Merge pull request #187 from stac-utils/feature/add-external-and-assets-endpoints
Feature/add external and assets endpoints
2 parents c4a0915 + 2f20440 commit a2280a9

File tree

12 files changed

+119
-12
lines changed

12 files changed

+119
-12
lines changed

CHANGES.md

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

33
## Unreleased
44

5+
* add `/collections/{collection_id}/items/{item_id}/assets/{asset_id}` optional endpoints (`TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS=TRUE|FALSE`)
6+
* add `/external` optional endpoints (`TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS=TRUE|FALSE`)
57
* add `cachecontrol_exclude_paths` attribute in `ApiSettings` to let users decide if some path should not have cache-control headers (defaults is to exclude `/list`)
68
* Add PgstacSettings such that the user can provide their own default settings for PgSTAC search
79

benchmark/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
### Start DB
33
```bash
4-
$ docker-compose up database
4+
$ docker compose up database
55
```
66

77
### Add items/collections to the db

docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
tiler:
53
container_name: tiler-pgstac

docs/src/endpoints/index.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@ title: Endpoints
55
---
66

77
<p align="center">
8-
<img alt="titiler-pgstac OpenAPI documentation" src="https://github.com/stac-utils/titiler-pgstac/assets/10407788/5269249e-4005-4574-937a-b3563b2df2f5"/>
8+
<img alt="titiler-pgstac OpenAPI documentation" src="https://github.com/user-attachments/assets/3f6b6b35-c54a-4932-98fc-6c2e11abd19a"/>
99
</p>
1010

11-
By default the main application (`titiler.pgstac.main.app`) provides three sets of endpoints:
11+
By default the main application (`titiler.pgstac.main.app`) provides three sets of endpoints of access raster dataset:
1212

1313
- [**Searches**](searches_endpoints.md): Dynamic **mosaic** tiler based on PgSTAC Search Query
1414
- [**Collections**](collections_endpoints.md): Dynamic **mosaic** tiler based on STAC Collection
1515
- [**Items**](items_endpoints.md): Dynamic tiler for single STAC item (stored in PgSTAC)
16-
- [**TileMatrixSet**](tms_endpoints.md): Available TileMatrixSets for the service
16+
17+
Some optional endpoints:
18+
19+
- [**Assets**](https://developmentseed.org/titiler/advanced/endpoints_factories/#endpoints) (external link): Dynamic tiler a single STAC Asset (stored in PgSTAC), enabled setting `TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS=TRUE`
20+
- [**External Dataset**](https://developmentseed.org/titiler/advanced/endpoints_factories/#endpoints) (external link): Dynamic tiler a single Cloud Optimized dataset, enabled setting `TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS=TRUE`
21+
22+
And some `metadata` endpoints:
23+
24+
- [**TileMatrixSets**](tms_endpoints.md): Available TileMatrixSets for the service
25+
- [**Algorithms**](https://developmentseed.org/titiler/endpoints/algorithms/) (external link): Available Algorithms for the service
26+
- [**Colormaps**](https://developmentseed.org/titiler/endpoints/colormaps/) (external link): Available Colormaps for the service

docs/src/intro.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ By default the main application (`titiler.pgstac.main.app`) provides three sets
1010

1111
- `/collections/{collection_id}/items/{item_id}`: Dynamic tiler for single STAC item (stored in PgSTAC)
1212

13+
Two other sets of endpoints can be enabled using environment variable:
14+
15+
- `/collections/{collection_id}/items/{item_id}/assets/{asset_id}`: Dynamic tiler of single STAC Asset (stored in PgSTAC), enabled setting `TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS=TRUE`
16+
17+
- `/external`: Dynamic tiler of single Cloud Optimized dataset, enabled setting `TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS=TRUE`
18+
1319
## STAC Searches - `/searches/{search_id}`
1420

1521
#### Register a PgSTAC `Search` request

docs/src/notebooks/demo.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"In order to run this demo you'll need to have a PgSTAC database and the titiler.pgstac application running. The easiest way to launch them is to use the repo's docker-compose.yml\n",
1212
"\n",
1313
"```\n",
14-
"docker-compose up tiler\n",
14+
"docker compose up tiler\n",
1515
"```\n",
1616
"\n",
1717
"\n",

tests/conftest.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,12 @@ def app(database_url, monkeypatch):
9595
monkeypatch.delenv("AWS_PROFILE", raising=False)
9696
monkeypatch.setenv("TITILER_PGSTAC_CACHE_DISABLE", "TRUE")
9797
monkeypatch.setenv("TITILER_PGSTAC_API_DEBUG", "TRUE")
98+
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS", "TRUE")
99+
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS", "TRUE")
98100

99101
monkeypatch.setenv("DATABASE_URL", str(database_url))
100102

101103
from titiler.pgstac.main import app
102104

103-
# Remove middlewares https://github.com/encode/starlette/issues/472
104-
# app.user_middleware = []
105-
# app.middleware_stack = app.build_middleware_stack()
106-
107105
with TestClient(app) as app:
108106
yield app

tests/test_optional_endpoints.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""test external cog and asset endpoints."""
2+
3+
from unittest.mock import patch
4+
5+
from .conftest import mock_rasterio_open
6+
7+
8+
@patch("rio_tiler.io.rasterio.rasterio")
9+
def test_cog_assets(rio, app):
10+
"""test STAC Assets endpoints."""
11+
rio.open = mock_rasterio_open
12+
13+
response = app.get(
14+
"/collections/noaa-emergency-response/items/20200307aC0853900w361030/assets/cog/info",
15+
)
16+
assert response.status_code == 200
17+
resp = response.json()
18+
assert resp["bounds"]
19+
20+
response = app.get(
21+
"/collections/noaa-emergency-response/items/20200307aC0853900w361030/assets/cog/WebMercatorQuad/tilejson.json",
22+
)
23+
assert response.status_code == 200
24+
resp = response.json()
25+
assert resp["tilejson"]
26+
27+
28+
def test_external_cog(app):
29+
"""test external cog endpoints."""
30+
response = app.get(
31+
"/external/info",
32+
params={"url": "tests/fixtures/20200307aC0853900w361030n.tif"},
33+
)
34+
assert response.status_code == 200
35+
resp = response.json()
36+
assert resp["bounds"]
37+
38+
response = app.get(
39+
"/external/WebMercatorQuad/tilejson.json",
40+
params={"url": "tests/fixtures/20200307aC0853900w361030n.tif"},
41+
)
42+
assert response.status_code == 200
43+
resp = response.json()
44+
assert resp["tilejson"]

titiler/pgstac/db.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ async def connect_to_db(
3131
max_idle=settings.db_max_idle,
3232
num_workers=settings.db_num_workers,
3333
kwargs=pool_kwargs,
34+
open=True,
3435
)
3536

3637
# Make sure the pool is ready

titiler/pgstac/dependencies.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ def ItemIdParams(
231231
return get_stac_item(request.app.state.dbpool, collection_id, item_id)
232232

233233

234+
def AssetIdParams(
235+
request: Request,
236+
collection_id: Annotated[
237+
str,
238+
Path(description="STAC Collection Identifier"),
239+
],
240+
item_id: Annotated[str, Path(description="STAC Item Identifier")],
241+
asset_id: Annotated[str, Path(description="STAC Asset Identifier")],
242+
) -> str:
243+
"""STAC Asset dependency."""
244+
item = get_stac_item(request.app.state.dbpool, collection_id, item_id)
245+
asset_info = item.assets[asset_id]
246+
return asset_info.get_absolute_href() or asset_info.href
247+
248+
234249
def TmsTileParams(
235250
z: Annotated[
236251
int,

titiler/pgstac/main.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
AlgorithmFactory,
2121
ColorMapFactory,
2222
MultiBaseTilerFactory,
23+
TilerFactory,
2324
TMSFactory,
2425
)
2526
from titiler.core.middleware import (
@@ -31,7 +32,12 @@
3132
from titiler.mosaic.errors import MOSAIC_STATUS_CODES
3233
from titiler.pgstac import __version__ as titiler_pgstac_version
3334
from titiler.pgstac.db import close_db_connection, connect_to_db
34-
from titiler.pgstac.dependencies import CollectionIdParams, ItemIdParams, SearchIdParams
35+
from titiler.pgstac.dependencies import (
36+
AssetIdParams,
37+
CollectionIdParams,
38+
ItemIdParams,
39+
SearchIdParams,
40+
)
3541
from titiler.pgstac.extensions import searchInfoExtension
3642
from titiler.pgstac.factory import (
3743
MosaicTilerFactory,
@@ -205,6 +211,30 @@ async def get_collection(request: Request, collection_id: str = Path()):
205211
prefix="/collections/{collection_id}/items/{item_id}",
206212
)
207213

214+
###############################################################################
215+
# STAC Assets Endpoints
216+
if settings.enable_assets_endpoints:
217+
asset = TilerFactory(
218+
path_dependency=AssetIdParams,
219+
router_prefix="/collections/{collection_id}/items/{item_id}/assets/{asset_id}",
220+
add_viewer=True,
221+
)
222+
app.include_router(
223+
asset.router,
224+
tags=["STAC Asset"],
225+
prefix="/collections/{collection_id}/items/{item_id}/assets/{asset_id}",
226+
)
227+
228+
###############################################################################
229+
# External Dataset Endpoints
230+
if settings.enable_external_dataset_endpoints:
231+
external_cog = TilerFactory(router_prefix="/external", add_viewer=True)
232+
app.include_router(
233+
external_cog.router,
234+
tags=["External Dataset"],
235+
prefix="/external",
236+
)
237+
208238
###############################################################################
209239
# Tiling Schemes Endpoints
210240
tms = TMSFactory()

titiler/pgstac/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class ApiSettings(BaseSettings):
2828
root_path: str = ""
2929
debug: bool = False
3030

31+
enable_assets_endpoints: bool = False
32+
enable_external_dataset_endpoints: bool = False
33+
3134
model_config = {
3235
"env_prefix": "TITILER_PGSTAC_API_",
3336
"env_file": ".env",

0 commit comments

Comments
 (0)