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
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"id": "flood_risk_service",
"description": "Benchmark scenario for a coastal area near Ferrara, Italy. Tests inundation impact on population, built surface, and cereal cropland under SSP5-8.5 with 1.0m storm surge by 2040.",
"backend": "https://api.ideas.adamplatform.eu/",
"endpoint": "POST /",
"inputs": {
"confidence": "medium",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[12.146707532485465, 44.93552068972261],
[12.146707532485465, 44.832178039646664],
[12.389998034208674, 44.832178039646664],
[12.389998034208674, 44.93552068972261],
[12.146707532485465, 44.93552068972261]
]
]
},
"ssp": "ssp585",
"storm_surge": "1_0",
"year": 2040
},
"outputs": {
"GHS_BUILT_S_E2020_GLOBE": 2560807.0,
"GHS_POP_E2020_GLOBE": 5385.0,
"cereals": 26.5,
"cereals_rice": 58.4
},
"tolerance": {
"type": "absolute",
"value": 0.0,
"note": "Results are deterministic given fixed inundation projection layers and static GHS/WorldCereal datasets. Exact match expected."
},
"performance": {
"max_response_time_seconds": 30,
"note": "Measured at ~22s on 2026-04-13. Threshold rounded up to 30s."
},
"links": [
{
"rel": "about",
"href": "https://api.ideas.adamplatform.eu/docs",
"title": "ADAM Platform API documentation"
}
]
}
23 changes: 23 additions & 0 deletions algorithm_catalog/meeo/flood_risk_service/openeo_udp/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from flask import Flask, request, jsonify
from generate import generate_process # import from your original logic

app = Flask(__name__)

# create the process only once
process = generate_process()

@app.route("/flood", methods=["POST"])
def flood_endpoint():
try:
data = request.get_json()

# use the function from generate.py
result = process["apply"](data)

return jsonify(result), 200

except Exception as e:
return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
app.run(debug=True, port=5000)
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"process_graph": {
"flood_risk_service_node": {
"process_id": "flood_risk_service",
"arguments": {
"area": {
"from_parameter": "area"
},
"year": {
"from_parameter": "year"
},
"ssp": {
"from_parameter": "ssp"
},
"storm_surge": {
"from_parameter": "storm_surge"
},
"confidence": {
"from_parameter": "confidence"
}
},
"result": true
}
},
"parameters": {
"area": {
"description": "Bounding box of the area [west, south, east, north]",
"schema": {
"type": "object",
"properties": {
"west": {
"type": "number"
},
"south": {
"type": "number"
},
"east": {
"type": "number"
},
"north": {
"type": "number"
}
},
"required": [
"west",
"south",
"east",
"north"
]
}
},
"year": {
"description": "Year of simulation",
"schema": {
"type": "string",
"enum": [
"2020",
"2040",
"2060",
"2080",
"2100",
"2120",
"2150",
"all"
]
},
"default": 2150
},
"ssp": {
"description": "SSP scenario",
"schema": {
"type": "string",
"enum": [
"ssp119",
"ssp126",
"ssp245",
"ssp370",
"ssp585",
"all"
]
}
},
"storm_surge": {
"description": "Storm surge level",
"schema": {
"type": "string",
"enum": [
"0_0",
"0_5",
"1_0",
"1_5",
"2_0",
"3_0",
"5_0",
"all"
]
}
},
"confidence": {
"description": "Confidence level",
"schema": {
"type": "string",
"enum": [
"low",
"medium",
"high"
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@

# openeo_udp — Flood Service Driver per OpenEO / APEX

Custom OpenEO driver for [ADAM platform's](https://api.ideas.adamplatform.eu) flood‑risk prediction service.

---

## Structure

```
openeo_udp/
├── app.py # Flask API to expose the process as an endpoint
├── generate.py # Definition of the custom OpenEO process
├── flood_risk_service.json # OpenEO‑standard process graph (JSON)
├── test_flood.py # Local test script for the Flask endpoint
└── README.md
```

---

## Installation

```bash
pip install requests flask openeo
```

---

## Start the Flask API

```bash
python app.py
```

The API will listen on **port 5000** (configurable in `app.py`).

### Endpoint

POST /flood

**Body JSON example:**

```json
{
"area": {"west": 0.6, "south": 40.7, "east": 0.7, "north": 40.8},
"year": "2150",
"ssp": "ssp585",
"storm_surge": "5_0",
"confidence": "medium"
}
```

---

## Direct usage with Python (without Flask)

```python
from generate import generate_process

process = generate_process()

context = {
"area": {"west": 0.6, "south": 40.7, "east": 0.7, "north": 40.8},
"year": "2150",
"ssp": "ssp585",
"storm_surge": "5_0",
"confidence": "medium",
}

result = process["apply"](context)
print(result)
```

---

## Local test of the Flask endpoint

```bash
python test_flood.py
```

`test_flood.py` sends a POST request to the `/flood` endpoint and prints:

- Status code
- JSON returned by the flood service

---

## Registration in the APEX catalog

The process must be registered **only once** in the back‑end catalog.

### Option A — Via REST API (curl)

```bash
curl -X PUT https://<apex-backend>/processes/flood_service_request -H "Content-Type: application/json" -d @process_graph.json
```

### Option B — Via OpenEO Python SDK

```python
import openeo, json

conn = openeo.connect("https://<apex-backend>")
# add here the chosen authentication method

with open("process_graph.json") as f:
pg = json.load(f)

conn.save_user_defined_process(
user_defined_process_id="flood_service_request",
process_graph=pg["process_graph"],
parameters=pg["parameters"],
summary=pg.get("summary", "Flood service request"),
description=pg.get("description", "Request flood service and return response"),
)
```

### Option C — Through the APEX UI

1. Go to **Processes** → **User-defined** → **New**.
2. Paste the contents of `process_graph.json`.
3. Save and publish.

---

## Parameters

| Parameter | Type | Allowed values | Default |
|---------------|--------|----------------------------------------- -------|------------|
| `area` | object | `{west, south, east, north}` in decimal degrees | — |
| `year` | string | 2020, 2040, 2060, 2080, 2100, 2120, 2150, all | `"2150"` |
| `ssp` | string | ssp119, ssp126, ssp245, ssp370, ssp585, all | — |
| `storm_surge` | string | 0_0, 0_5, 1_0, 1_5, 2_0, 3_0, 5_0, all | — |
| `confidence` | string | low, medium, high | `"medium"` |

> Nota: `area` must be an object with the keys "west", "south", "east", "north" in decimal degrees. Do not use coordinate lists.

---

## Composition with other OpenEO processes

```json
{
"process_graph": {
"flood_node": {
"process_id": "flood_service_request",
"arguments": {
"area": { "from_parameter": "area" },
"year": "2100",
"ssp": "ssp585",
"storm_surge": "1_0",
"confidence": "high"
}
},
"save_node": {
"process_id": "save_result",
"arguments": {
"data": { "from_node": "flood_node" },
"format": "JSON"
},
"result": true
}
}
}
```

---

## Notes for APEX integration

- **`process_id`**: `flood_service_request`
- The `"apply"` field in `generate_process()` is the callable invoked by the Python runtime; it is ignored in the JSON serialization.
- Il back-end must have network access to `https://api.ideas.adamplatform.eu/`.
- Timeout is set to 120 seconds: increase it in generate.py for very large areas or for requests using the `"all"` parameter.

---

## References

- [openEO API — Processes](https://api.openeo.org/#tag/Process-Discovery)
- [openEO Python Client](https://open-eo.github.io/openeo-python-client/)
- [ADAM Platform API](https://api.ideas.adamplatform.eu/docs)
Loading
Loading