diff --git a/CHANGES.md b/CHANGES.md index b4484479..cbe3508f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ ### titiler.core * Add `use_epsg` parameter to WMTS endpoint to resolve ArcMAP issues and fix XML formating (author @gadomski, https://github.com/developmentseed/titiler/pull/782) +* Add more OpenAPI metadata for algorithm (author @JinIgarashi, https://github.com/developmentseed/titiler/pull/783) ### titiler.application diff --git a/src/titiler/core/titiler/core/algorithm/base.py b/src/titiler/core/titiler/core/algorithm/base.py index cc285562..33ee9c37 100644 --- a/src/titiler/core/titiler/core/algorithm/base.py +++ b/src/titiler/core/titiler/core/algorithm/base.py @@ -32,6 +32,9 @@ def __call__(self, img: ImageData) -> ImageData: class AlgorithmMetadata(BaseModel): """Algorithm metadata.""" + title: Optional[str] = None + description: Optional[str] = None + inputs: Dict outputs: Dict parameters: Dict diff --git a/src/titiler/core/titiler/core/algorithm/dem.py b/src/titiler/core/titiler/core/algorithm/dem.py index 882049e3..2976c489 100644 --- a/src/titiler/core/titiler/core/algorithm/dem.py +++ b/src/titiler/core/titiler/core/algorithm/dem.py @@ -1,6 +1,7 @@ """titiler.core.algorithm DEM.""" import numpy +from pydantic import Field from rasterio import windows from rio_tiler.colormap import apply_cmap, cmap from rio_tiler.models import ImageData @@ -12,10 +13,13 @@ class HillShade(BaseAlgorithm): """Hillshade.""" + title: str = "Hillshade" + description: str = "Create hillshade from DEM dataset." + # parameters - azimuth: int = 90 - angle_altitude: float = 90.0 - buffer: int = 3 + azimuth: int = Field(90, ge=0, lt=360) + angle_altitude: float = Field(90.0, ge=-90.0, lt=90.0) + buffer: int = Field(3, ge=0, lt=99) # metadata input_nbands: int = 1 @@ -61,11 +65,14 @@ class Contours(BaseAlgorithm): Original idea from https://custom-scripts.sentinel-hub.com/dem/contour-lines/ """ + title: str = "Contours" + description: str = "Create contours from DEM dataset." + # parameters - increment: int = 35 - thickness: int = 1 - minz: int = -12000 - maxz: int = 8000 + increment: int = Field(35, ge=0, lt=999) + thickness: int = Field(1, ge=0, lt=10) + minz: int = Field(-12000, ge=-99999, lt=99999) + maxz: int = Field(8000, ge=-99999, lt=99999) # metadata input_nbands: int = 1 @@ -99,6 +106,9 @@ def __call__(self, img: ImageData) -> ImageData: class Terrarium(BaseAlgorithm): """Encode DEM into RGB (Mapzen Terrarium).""" + title: str = "Terrarium" + description: str = "Encode DEM into RGB (Mapzen Terrarium)." + # metadata input_nbands: int = 1 output_nbands: int = 3 @@ -122,9 +132,12 @@ def __call__(self, img: ImageData) -> ImageData: class TerrainRGB(BaseAlgorithm): """Encode DEM into RGB (Mapbox Terrain RGB).""" + title: str = "Terrarium" + description: str = "Encode DEM into RGB (Mapbox Terrain RGB)." + # parameters - interval: float = 0.1 - baseval: float = -10000.0 + interval: float = Field(0.1, ge=0.0, lt=1.0) + baseval: float = Field(-10000.0, ge=-99999.0, lt=99999.0) # metadata input_nbands: int = 1 diff --git a/src/titiler/core/titiler/core/algorithm/index.py b/src/titiler/core/titiler/core/algorithm/index.py index 2d47c4a7..e0351d77 100644 --- a/src/titiler/core/titiler/core/algorithm/index.py +++ b/src/titiler/core/titiler/core/algorithm/index.py @@ -11,6 +11,9 @@ class NormalizedIndex(BaseAlgorithm): """Normalized Difference Index.""" + title: str = "Normalized Difference Index" + description: str = "Compute normalized difference index from two bands." + # metadata input_nbands: int = 2 output_nbands: int = 1 diff --git a/src/titiler/core/titiler/core/factory.py b/src/titiler/core/titiler/core/factory.py index 7cb9b7fd..5fb38772 100644 --- a/src/titiler/core/titiler/core/factory.py +++ b/src/titiler/core/titiler/core/factory.py @@ -1667,6 +1667,15 @@ def metadata(algorithm: BaseAlgorithm) -> AlgorithmMetadata: """Algorithm Metadata""" props = algorithm.model_json_schema()["properties"] + # title and description + info = { + k: v["default"] + for k, v in props.items() + if k == "title" or k == "description" + } + title = info.get("title", None) + description = info.get("description", None) + # Inputs Metadata ins = { k.replace("input_", ""): v["default"] @@ -1685,9 +1694,18 @@ def metadata(algorithm: BaseAlgorithm) -> AlgorithmMetadata: params = { k: v for k, v in props.items() - if not k.startswith("input_") and not k.startswith("output_") + if not k.startswith("input_") + and not k.startswith("output_") + and k != "title" + and k != "description" } - return AlgorithmMetadata(inputs=ins, outputs=outs, parameters=params) + return AlgorithmMetadata( + title=title, + description=description, + inputs=ins, + outputs=outs, + parameters=params, + ) @self.router.get( "/algorithms",