Skip to content

Commit

Permalink
Merge pull request #187 from stac-utils/feature/add-external-and-asse…
Browse files Browse the repository at this point in the history
…ts-endpoints

Feature/add external and assets endpoints
  • Loading branch information
vincentsarago authored Sep 3, 2024
2 parents c4a0915 + 2f20440 commit a2280a9
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

* add `/collections/{collection_id}/items/{item_id}/assets/{asset_id}` optional endpoints (`TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS=TRUE|FALSE`)
* add `/external` optional endpoints (`TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS=TRUE|FALSE`)
* 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`)
* Add PgstacSettings such that the user can provide their own default settings for PgSTAC search

Expand Down
2 changes: 1 addition & 1 deletion benchmark/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

### Start DB
```bash
$ docker-compose up database
$ docker compose up database
```

### Add items/collections to the db
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3'

services:
tiler:
container_name: tiler-pgstac
Expand Down
16 changes: 13 additions & 3 deletions docs/src/endpoints/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@ title: Endpoints
---

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

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

- [**Searches**](searches_endpoints.md): Dynamic **mosaic** tiler based on PgSTAC Search Query
- [**Collections**](collections_endpoints.md): Dynamic **mosaic** tiler based on STAC Collection
- [**Items**](items_endpoints.md): Dynamic tiler for single STAC item (stored in PgSTAC)
- [**TileMatrixSet**](tms_endpoints.md): Available TileMatrixSets for the service

Some optional endpoints:

- [**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`
- [**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`

And some `metadata` endpoints:

- [**TileMatrixSets**](tms_endpoints.md): Available TileMatrixSets for the service
- [**Algorithms**](https://developmentseed.org/titiler/endpoints/algorithms/) (external link): Available Algorithms for the service
- [**Colormaps**](https://developmentseed.org/titiler/endpoints/colormaps/) (external link): Available Colormaps for the service
6 changes: 6 additions & 0 deletions docs/src/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ By default the main application (`titiler.pgstac.main.app`) provides three sets

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

Two other sets of endpoints can be enabled using environment variable:

- `/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`

- `/external`: Dynamic tiler of single Cloud Optimized dataset, enabled setting `TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS=TRUE`

## STAC Searches - `/searches/{search_id}`

#### Register a PgSTAC `Search` request
Expand Down
2 changes: 1 addition & 1 deletion docs/src/notebooks/demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"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",
"\n",
"```\n",
"docker-compose up tiler\n",
"docker compose up tiler\n",
"```\n",
"\n",
"\n",
Expand Down
6 changes: 2 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,12 @@ def app(database_url, monkeypatch):
monkeypatch.delenv("AWS_PROFILE", raising=False)
monkeypatch.setenv("TITILER_PGSTAC_CACHE_DISABLE", "TRUE")
monkeypatch.setenv("TITILER_PGSTAC_API_DEBUG", "TRUE")
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS", "TRUE")
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS", "TRUE")

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

from titiler.pgstac.main import app

# Remove middlewares https://github.com/encode/starlette/issues/472
# app.user_middleware = []
# app.middleware_stack = app.build_middleware_stack()

with TestClient(app) as app:
yield app
44 changes: 44 additions & 0 deletions tests/test_optional_endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""test external cog and asset endpoints."""

from unittest.mock import patch

from .conftest import mock_rasterio_open


@patch("rio_tiler.io.rasterio.rasterio")
def test_cog_assets(rio, app):
"""test STAC Assets endpoints."""
rio.open = mock_rasterio_open

response = app.get(
"/collections/noaa-emergency-response/items/20200307aC0853900w361030/assets/cog/info",
)
assert response.status_code == 200
resp = response.json()
assert resp["bounds"]

response = app.get(
"/collections/noaa-emergency-response/items/20200307aC0853900w361030/assets/cog/WebMercatorQuad/tilejson.json",
)
assert response.status_code == 200
resp = response.json()
assert resp["tilejson"]


def test_external_cog(app):
"""test external cog endpoints."""
response = app.get(
"/external/info",
params={"url": "tests/fixtures/20200307aC0853900w361030n.tif"},
)
assert response.status_code == 200
resp = response.json()
assert resp["bounds"]

response = app.get(
"/external/WebMercatorQuad/tilejson.json",
params={"url": "tests/fixtures/20200307aC0853900w361030n.tif"},
)
assert response.status_code == 200
resp = response.json()
assert resp["tilejson"]
1 change: 1 addition & 0 deletions titiler/pgstac/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ async def connect_to_db(
max_idle=settings.db_max_idle,
num_workers=settings.db_num_workers,
kwargs=pool_kwargs,
open=True,
)

# Make sure the pool is ready
Expand Down
15 changes: 15 additions & 0 deletions titiler/pgstac/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,21 @@ def ItemIdParams(
return get_stac_item(request.app.state.dbpool, collection_id, item_id)


def AssetIdParams(
request: Request,
collection_id: Annotated[
str,
Path(description="STAC Collection Identifier"),
],
item_id: Annotated[str, Path(description="STAC Item Identifier")],
asset_id: Annotated[str, Path(description="STAC Asset Identifier")],
) -> str:
"""STAC Asset dependency."""
item = get_stac_item(request.app.state.dbpool, collection_id, item_id)
asset_info = item.assets[asset_id]
return asset_info.get_absolute_href() or asset_info.href


def TmsTileParams(
z: Annotated[
int,
Expand Down
32 changes: 31 additions & 1 deletion titiler/pgstac/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
AlgorithmFactory,
ColorMapFactory,
MultiBaseTilerFactory,
TilerFactory,
TMSFactory,
)
from titiler.core.middleware import (
Expand All @@ -31,7 +32,12 @@
from titiler.mosaic.errors import MOSAIC_STATUS_CODES
from titiler.pgstac import __version__ as titiler_pgstac_version
from titiler.pgstac.db import close_db_connection, connect_to_db
from titiler.pgstac.dependencies import CollectionIdParams, ItemIdParams, SearchIdParams
from titiler.pgstac.dependencies import (
AssetIdParams,
CollectionIdParams,
ItemIdParams,
SearchIdParams,
)
from titiler.pgstac.extensions import searchInfoExtension
from titiler.pgstac.factory import (
MosaicTilerFactory,
Expand Down Expand Up @@ -205,6 +211,30 @@ async def get_collection(request: Request, collection_id: str = Path()):
prefix="/collections/{collection_id}/items/{item_id}",
)

###############################################################################
# STAC Assets Endpoints
if settings.enable_assets_endpoints:
asset = TilerFactory(
path_dependency=AssetIdParams,
router_prefix="/collections/{collection_id}/items/{item_id}/assets/{asset_id}",
add_viewer=True,
)
app.include_router(
asset.router,
tags=["STAC Asset"],
prefix="/collections/{collection_id}/items/{item_id}/assets/{asset_id}",
)

###############################################################################
# External Dataset Endpoints
if settings.enable_external_dataset_endpoints:
external_cog = TilerFactory(router_prefix="/external", add_viewer=True)
app.include_router(
external_cog.router,
tags=["External Dataset"],
prefix="/external",
)

###############################################################################
# Tiling Schemes Endpoints
tms = TMSFactory()
Expand Down
3 changes: 3 additions & 0 deletions titiler/pgstac/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class ApiSettings(BaseSettings):
root_path: str = ""
debug: bool = False

enable_assets_endpoints: bool = False
enable_external_dataset_endpoints: bool = False

model_config = {
"env_prefix": "TITILER_PGSTAC_API_",
"env_file": ".env",
Expand Down

0 comments on commit a2280a9

Please sign in to comment.