diff --git a/CHANGES.md b/CHANGES.md index 732fa4c2..7d75e1d9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ * Adding `transform`, `height` and `width` attributes (outside init) for `SpatialMixin` class * Moved `_dst_geom_in_tms_crs` from Reader to `SpatialMixin` class **breaking change** * Removed use of rasterio's `is_tiled` method +* Enable **Alternate** asset's HREF for STAC by using `RIO_TILER_STAC_ALTERNATE_KEY` environment variable # 6.7.0 (2024-09-05) diff --git a/rio_tiler/io/stac.py b/rio_tiler/io/stac.py index 6887efff..415d3e1e 100644 --- a/rio_tiler/io/stac.py +++ b/rio_tiler/io/stac.py @@ -42,6 +42,8 @@ "application/x-hdf", } +STAC_ALTERNATE_KEY = os.environ.get("RIO_TILER_STAC_ALTERNATE_KEY", None) + def aws_get_object( bucket: str, @@ -313,6 +315,11 @@ def _get_asset_info(self, asset: str) -> AssetInfo: url=asset_info.get_absolute_href() or asset_info.href, metadata=extras, ) + + if STAC_ALTERNATE_KEY and extras.get("alternate"): + if alternate := extras["alternate"].get(STAC_ALTERNATE_KEY): + info["url"] = alternate["href"] + if asset_info.media_type: info["media_type"] = asset_info.media_type diff --git a/tests/fixtures/stac_alternate.json b/tests/fixtures/stac_alternate.json new file mode 100644 index 00000000..0bd8f999 --- /dev/null +++ b/tests/fixtures/stac_alternate.json @@ -0,0 +1,85 @@ +{ + "stac_version": "0.9.0", + "stac_extensions": [ + "https://stac-extensions.github.io/file/v2.1.0/schema.json", + "https://stac-extensions.github.io/alternate-assets/v1.2.0/schema.json" + ], + "type": "Feature", + "id": "JQT-123456789", + "bbox": [-81.3085227080129, 32.10817938759764, -78.81735409341113, 34.22870275071835], + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -81.3085227080129, + 32.10817938759764 + ], + [ + -78.81735409341113, + 32.10817938759764 + ], + [ + -78.81735409341113, + 34.22870275071835 + ], + [ + -81.3085227080129, + 34.22870275071835 + ], + [ + -81.3085227080129, + 32.10817938759764 + ] + ] + ] + }, + "properties": { + "datetime": "2016-05-03T13:21:30.040Z", + "collection": "JQT" + }, + "links": [ + { + "rel": "self", + "href": "http://cool-sat.com/catalog/JQT/a-fake-item.json" + }, + { + "rel": "collection", + "href": "http://cool-sat.com/catalog.json" + } + ], + "assets": { + "red": { + "href": "http://somewhere-over-the-rainbow.io/red.tif", + "title": "red", + "file:header_size": 16384, + "alternate:name": "HTTPS", + "alternate": { + "s3": { + "href": "s3://somewhere-over-the-rainbow.io/red.tif", + "alternate:name": "S3" + } + } + }, + "green": { + "href": "http://somewhere-over-the-rainbow.io/green.tif", + "title": "green", + "file:header_size": 30000 + }, + "blue": { + "href": "http://somewhere-over-the-rainbow.io/blue.tif", + "title": "blue", + "file:header_size": 20000 + }, + "lowres": { + "href": "http://somewhere-over-the-rainbow.io/lowres.tif", + "title": "lowres" + }, + "thumbnail": { + "href": "http://cool-sat.com/catalog/a-fake-item/thumbnail.png", + "title": "Thumbnail", + "type": "image/png", + "roles": [ "thumbnail" ] + } + } +} diff --git a/tests/test_io_stac.py b/tests/test_io_stac.py index 5fc646de..97ed00d0 100644 --- a/tests/test_io_stac.py +++ b/tests/test_io_stac.py @@ -33,6 +33,7 @@ STAC_GDAL_PATH = os.path.join(PREFIX, "stac_headers.json") STAC_RASTER_PATH = os.path.join(PREFIX, "stac_raster.json") STAC_WRONGSTATS_PATH = os.path.join(PREFIX, "stac_wrong_stats.json") +STAC_ALTERNATE_PATH = os.path.join(PREFIX, "stac_alternate.json") with open(STAC_PATH) as f: item = json.loads(f.read()) @@ -1014,3 +1015,12 @@ def _get_reader(self, asset_info: AssetInfo) -> Tuple[Type[BaseReader], Dict]: info = stac._get_asset_info("red") assert info["media_type"] == "image/tiff; application=geotiff" assert stac._get_reader(info) == (Reader, {}) + + +@patch("rio_tiler.io.stac.STAC_ALTERNATE_KEY", "s3") +def test_alternate_assets(): + """Should return the alternate key""" + with STACReader(STAC_ALTERNATE_PATH) as stac: + assert stac._get_asset_info("red")["url"].startswith("s3://") + # fall back to href when alternate doesn't exist + assert stac._get_asset_info("blue")["url"].startswith("http://")