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"}