from fastapi import FastAPI
from fastapi.responses import FileResponse, HTMLResponse
import folium
import pandas as pd
import joblib
import requests
import os
app = FastAPI()
# -------------------
# Load Models
# -------------------
flood_model = joblib.load("best_flood_model.pkl")
wildfire_model = joblib.load("wildfire_model_gb.pkl")
cities_df = pd.read_csv("cyprus_cities_full.csv")
FLOOD_MAP = "flood_map.html"
WILDFIRE_MAP = "wildfire_map.html"
# -------------------
# Home Page
# -------------------
@app.get("/", response_class=HTMLResponse)
def home():
return """
Cyprus Multi-Hazard Risk Platform
Generate real-time flood and wildfire risk maps
using weather data and machine learning.
View Flood Map
View Wildfire Map
"""
# -------------------
# Flood Map
# -------------------
@app.post("/generate-flood-map")
def generate_flood_map():
m = folium.Map(location=[35.1,33.4], zoom_start=8)
for _, row in cities_df.iterrows():
city = row["city"]
lat = row["lat"]
lon = row["lon"]
url = (
"https://api.open-meteo.com/v1/forecast"
f"?latitude={lat}"
f"&longitude={lon}"
"&daily=precipitation_sum"
"&forecast_days=7"
"&timezone=auto"
)
data = requests.get(url).json()
daily_rain = data["daily"]["precipitation_sum"]
rain_mm = daily_rain[-1]
rain_3d = sum(daily_rain[-3:])
rain_7d = sum(daily_rain)
X = pd.DataFrame([{
"rain_mm": rain_mm,
"rain_3d": rain_3d,
"rain_7d": rain_7d,
"rain_intensity": rain_mm*0.6 + rain_3d*0.4,
"soil_saturation": rain_7d/(rain_3d+1),
"storm_index": rain_mm + rain_3d + rain_7d
}])
prob = flood_model.predict_proba(X)[0][1]
if prob < 0.33:
color="green"
label="Low"
elif prob < 0.66:
color="orange"
label="Medium"
else:
color="red"
label="High"
folium.CircleMarker(
[lat,lon],
radius=7,
color=color,
fill=True,
fill_color=color,
popup=f"{city}
Flood Risk:{prob:.2f}
{label}"
).add_to(m)
m.save(FLOOD_MAP)
return {"status":"Flood map generated","view":"/view-flood-map"}
@app.get("/view-flood-map")
def view_flood_map():
if os.path.exists(FLOOD_MAP):
return FileResponse(FLOOD_MAP)
return {"error":"Generate flood map first"}
# -------------------
# Wildfire Map
# -------------------
@app.post("/generate-wildfire-map")
def generate_wildfire_map():
m = folium.Map(location=[35.1,33.4], zoom_start=8)
for _, row in cities_df.iterrows():
city = row["city"]
lat = row["lat"]
lon = row["lon"]
url = (
"https://api.open-meteo.com/v1/forecast"
f"?latitude={lat}"
f"&longitude={lon}"
"&daily=temperature_2m_max,wind_speed_10m_max"
"&forecast_days=7"
"&timezone=auto"
)
data = requests.get(url).json()
temp = data["daily"]["temperature_2m_max"][-1]
wind = data["daily"]["wind_speed_10m_max"][-1]
X = pd.DataFrame([{
"temperature": temp,
"wind_speed": wind
}])
prob = wildfire_model.predict_proba(X)[0][1]
if prob < 0.33:
color="green"
label="Low"
elif prob < 0.66:
color="orange"
label="Medium"
else:
color="red"
label="High"
folium.CircleMarker(
[lat,lon],
radius=7,
color=color,
fill=True,
fill_color=color,
popup=f"{city}
Wildfire Risk:{prob:.2f}
{label}"
).add_to(m)
m.save(WILDFIRE_MAP)
return {"status":"Wildfire map generated","view":"/view-wildfire-map"}
@app.get("/view-wildfire-map")
def view_wildfire_map():
if os.path.exists(WILDFIRE_MAP):
return FileResponse(WILDFIRE_MAP)
return {"error":"Generate wildfire map first"}