HANDBOOK_GUIDE2026-06-29
Rising Waters: Machine Learning Approach to Flood Prediction System ML Guide
By Rayan Syed
45 min read
Part 7: Flask API Backend
Save this script as app.py in your project folder.
7.1 Understanding Backend Web Servers & API Routing
In this phase, we build a local web backend using Flask.
- API Routing: Routing is the mechanism that maps network URLs (endpoints) to specific Python functions. In Flask, we define routes using
@app.route(). - JSON Exchange: JavaScript on the frontend will capture user entries and package them as JSON. The backend extracts this JSON (
request.get_json()), converts the values to floats/integers, and packs them into a NumPy array matching the exact structure used during model training. - Making Predictions: The Flask server loads our serialized model weights (
joblib.load('models/flood_model.joblib')) in memory. When it receives a request, it callsmodel.predict()and returns the boolean approved/rejected decision back to the client. - Why We Need a Server: You might wonder: why can’t we run predictions directly in browser JavaScript? In real-world applications, machine learning models can weigh several hundred megabytes. Loading these models directly into the user’s web browser would freeze their system or crash the page. Running the model on a dedicated backend server keeps the client lightweight and secure.
from flask import Flask, request, jsonify, render_template
import joblib
import numpy as np
import os
app = Flask(__name__)
# Load the saved model and scaler
MODEL_PATH = 'models/flood_model.joblib'
SCALER_PATH = 'models/scaler.joblib'
if not os.path.exists(MODEL_PATH) or not os.path.exists(SCALER_PATH):
print("ERROR: Model or Scaler not found! Please run train.py first.")
exit(1)
model = joblib.load(MODEL_PATH)
scaler = joblib.load(SCALER_PATH)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/predict', methods=['POST'])
def predict():
try:
data = request.get_json()
# Build features list in the exact order the model expects:
# Temp, Humidity, Cloud Cover, ANNUAL, Jan-Feb, Mar-May, Jun-Sep, Oct-Dec, avgjune, sub
features_raw = np.array([[
float(data['temp']),
float(data['humidity']),
float(data['cloud_cover']),
float(data['annual_rainfall']),
float(data['jan_feb']),
float(data['mar_may']),
float(data['jun_sep']),
float(data['oct_dec']),
float(data['avg_june']),
float(data['sub_index'])
]])
# Apply the StandardScaler fitted during training
features_scaled = scaler.transform(features_raw)
# Predict target (0 = No Flood, 1 = Flood)
prediction = model.predict(features_scaled)[0]
prediction_proba = model.predict_proba(features_scaled)[0]
result = {
'flood': int(prediction) == 1,
'flood_probability': float(prediction_proba[1]) * 100,
'no_flood_probability': float(prediction_proba[0]) * 100
}
return jsonify(result)
except Exception as e:
return jsonify({'error': str(e)}), 400
if __name__ == '__main__':
app.run(port=5000, debug=True)