BACK_TO_LOGS// STEP_7_OF_10
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 calls model.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)