A production-ready FastAPI microservice for human-in-the-loop AI decision making in flood disaster management. Uses Fuzzy Logic for risk assessment and AHP (Analytic Hierarchy Process) for household vulnerability evaluation.
- Explainable AI: Rule-based fuzzy logic and AHP (no black-box models)
- Real-time Data Integration:
- MongoDB Atlas for sensor data (water levels)
- Supabase PostgreSQL for household demographics
- Dual Assessment:
- Fuzzy Logic: Evaluates flood risk based on water levels and trends
- AHP: Calculates household vulnerability based on vulnerable members
- Human-in-the-Loop: Support for human override of AI recommendations
- Production-Ready:
- Type hints and Pydantic validation
- Comprehensive logging
- Error handling
- CORS and security middleware
app/
βββ main.py # FastAPI app entry point
βββ models/
β βββ __init__.py
β βββ schemas.py # Pydantic models for request/response
βββ routes/
β βββ __init__.py
β βββ decision.py # API endpoint handlers
βββ services/
β βββ __init__.py
β βββ fuzzy_service.py # Fuzzy logic risk assessment
β βββ ahp_service.py # AHP vulnerability scoring
β βββ decision_service.py # Combined decision engine
βββ database/
βββ __init__.py
βββ mongodb.py # MongoDB Atlas integration
βββ supabase.py # Supabase PostgreSQL integration
requirements.txt # Python dependencies
runtime.txt # Python version for deployment
.env.example # Environment variables template
- Python 3.10 or higher
- MongoDB Atlas account (free tier available)
- Supabase account (free tier available)
- Git
-
Clone and navigate to project
cd "Human in the loop AI"
-
Create Python virtual environment
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies
pip install -r requirements.txt
-
Configure environment variables
cp .env.example .env
Edit
.envand add your credentials:MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/disaster_management?retryWrites=true SUPABASE_URL=https://your-project.supabase.co SUPABASE_KEY=your-anon-key
-
Setup MongoDB Atlas (if not already done)
- Create free cluster at https://www.mongodb.com/cloud/atlas
- Create database named
disaster_management - Create collection:
sensor_readings - Sample document structure:
{ "barangay_id": 1, "water_level": 65.5, "timestamp": ISODate("2024-05-03T10:30:00Z") }
-
Setup Supabase (if not already done)
- Create project at https://supabase.com
- Create table
residents:CREATE TABLE residents ( id SERIAL PRIMARY KEY, barangay_id INTEGER NOT NULL, age INTEGER, is_pregnant BOOLEAN DEFAULT FALSE, is_pwd BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW() );
-
Run the development server
uvicorn app.main:app --reload --host 0.0.0.0 --port 10000
Server will be available at:
http://localhost:10000 -
Access API documentation
- Swagger UI: http://localhost:10000/docs
- ReDoc: http://localhost:10000/redoc
GET /healthResponse:
{
"status": "healthy",
"message": "AI Decision Service is running"
}POST /api/v1/decision
Content-Type: application/json
{
"barangay_id": 1
}Response:
{
"barangay_id": 1,
"risk_level": "HIGH",
"priority_score": 0.82,
"recommended_action": "IMMEDIATE RELIEF",
"confidence_score": 0.85,
"explanation": "High water level (120cm) with rising trend and vulnerable household members (2 elderly, 1 infant) indicate immediate relief is needed (confidence: 85%).",
"override_action": null,
"fuzzy_explanation": "Average water level is 120.0cm, in danger zone (100-150cm). Water levels are RISING, situation deteriorating. Risk assessment: HIGH (confidence: 95%)",
"ahp_explanation": "Household Vulnerability Assessment: 82% priority. Vulnerable members: Elderly (2), Infants (1). Priority level: Critical. Household has 2 elderly resident(s) who may need mobility assistance. Household has 1 infant(s) requiring special evacuation support."
}curl -X POST http://localhost:10000/api/v1/decision \
-H "Content-Type: application/json" \
-d '{"barangay_id": 1}'import requests
response = requests.post(
"http://localhost:10000/api/v1/decision",
json={"barangay_id": 1}
)
print(response.json())Navigate to http://localhost:10000/docs and use the interactive Swagger UI.
Assesses flood risk based on water level sensor data:
Input:
avg_water_level: Average water level (cm) over last 10 minutesmax_water_level: Peak water level in that periodtrend: Rising, falling, or stable
Thresholds:
- LOW_THRESHOLD: 50 cm
- MEDIUM_THRESHOLD: 100 cm
- CRITICAL_THRESHOLD: 150 cm
Rules:
- If avg < 50cm β LOW risk
- If 50cm β€ avg β€ 100cm β MEDIUM risk
- If avg > 100cm β HIGH risk
- If trend is rising β increase risk by 15%
- If trend is falling β decrease risk by 15%
- If recent spike (max > 150cm) β increase risk by 10%
Output: Risk level (LOW/MEDIUM/HIGH) with confidence score 0-1
Calculates household vulnerability using weighted scoring:
Vulnerability Factors:
- Elderly (age β₯ 60): Weight 35%
- Infants (age β€ 2): Weight 40%
- Pregnant residents: Weight 15%
- PWD (Persons with Disabilities): Weight 10%
Scoring:
- Each factor contributes based on count and household composition
- Infants: 3x weight (highest vulnerability)
- Elderly: 2.5x weight
- Pregnant: 1.5x weight
- PWD: 1.2x weight
Output: Priority score 0-1 (0 = low, 1 = critical vulnerability)
Combines risk + priority into action recommendation:
| Risk Level | Priority | Recommendation |
|---|---|---|
| HIGH | HIGH/CRITICAL | IMMEDIATE RELIEF |
| HIGH | MODERATE | PREPARE |
| HIGH | LOW | PREPARE |
| MEDIUM | HIGH/CRITICAL | IMMEDIATE RELIEF |
| MEDIUM | MODERATE | PREPARE |
| MEDIUM | LOW | PREPARE |
| LOW | HIGH | PREPARE |
| LOW | LOW | SAFE |
Human Override: API supports passing override_action to override AI recommendation.
- GitHub account with repository
- Render account (free tier available at https://render.com)
-
Initialize git repository (if not already done):
cd "Human in the loop AI" git init git add . git commit -m "Initial commit: AI Decision Service"
-
Create repository on GitHub and push:
git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO.git git branch -M main git push -u origin main
- Go to https://render.com and sign in
- Click New + β Web Service
- Select your GitHub repository
- Configure the service:
- Name:
ai-decision-service - Environment:
Python 3 - Build Command:
pip install -r requirements.txt - Start Command:
uvicorn app.main:app --host 0.0.0.0 --port 10000 - Instance Type: Starter (free tier)
- Name:
In Render dashboard, go to your service and click Environment. Add:
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/disaster_management?retryWrites=true
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-key
ENV=production
PORT=10000
ALLOWED_ORIGINS=https://yourdomain.com,https://api.yourdomain.com
TRUSTED_HOSTS=yourdomain.com,api.yourdomain.com
- Click Deploy button
- Wait for deployment to complete (usually 2-5 minutes)
- Your service URL will be:
https://ai-decision-service.onrender.com
curl https://ai-decision-service.onrender.com/health
# Test the decision endpoint
curl -X POST https://ai-decision-service.onrender.com/api/v1/decision \
-H "Content-Type: application/json" \
-d '{"barangay_id": 1}'Important: Whitelist Render IP address in MongoDB Atlas:
- Go to MongoDB Atlas Dashboard
- Network Access β IP Whitelist
- Add:
0.0.0.0/0(or specific Render IP if available)
If accessing from frontend, ensure CORS is configured in Supabase:
- Go to Supabase Dashboard
- Authentication β URL Configuration
- Add your domain to Redirect URLs
{
"_id": ObjectId,
"barangay_id": 1,
"water_level": 65.5,
"location": "Bridge near Barangay 1",
"timestamp": ISODate("2024-05-03T10:30:00Z")
}id | INTEGER PRIMARY KEY
barangay_id | INTEGER NOT NULL
age | INTEGER
is_pregnant | BOOLEAN DEFAULT FALSE
is_pwd | BOOLEAN DEFAULT FALSE
created_at | TIMESTAMP DEFAULT NOW()The service logs important events:
2024-05-03 10:30:45 - app.services.decision_service - INFO - Making decision for barangay 1
2024-05-03 10:30:46 - app.services.fuzzy_service - INFO - Risk assessment: level=HIGH, confidence=0.95, trend=rising
2024-05-03 10:30:46 - app.services.ahp_service - INFO - AHP Priority Score: 0.820 - Factors: Elderly (2), Infants (1)
2024-05-03 10:30:46 - app.services.decision_service - INFO - Decision made for barangay 1: IMMEDIATE RELIEF (confidence: 0.85)
Check logs:
- Local: Console output when running with
--reload - Render: Dashboard β Logs tab
- Environment Variables: Never commit
.envfile - CORS: Restrict to known origins
- Input Validation: Pydantic validates all inputs
- Error Handling: Errors don't leak sensitive info
- HTTPS: Always use HTTPS in production (Render provides free SSL)
- Database: Use strong passwords and network restrictions
Error: Failed to connect to MongoDB: connection refused
Solution: Check MONGODB_URI in .env and whitelist IP in MongoDB Atlas
Error: Failed to connect to Supabase: [Errno -2] Name or service not known
Solution: Verify SUPABASE_URL and SUPABASE_KEY
WARNING - No sensor data found for barangay 1
Solution: Insert test data into MongoDB sensor_readings collection
OSError: [Errno 48] Address already in use
Solution: Change port in command: --port 10001
This project is part of a thesis on Human-in-the-Loop AI for disaster management.
Senior Backend Engineer & AI Systems Architect
For production deployment, ensure:
- β Database backups configured
- β Monitoring and alerting set up
- β Load testing completed
- β Security audit passed
- β Documentation reviewed