Comprehensive Water & Sanitation Analytics for Uganda, Cameroon, Lesotho, and Malawi
A powerful Streamlit dashboard empowering utility managers with data-driven insights for operational efficiency, financial sustainability, service quality, and equitable access.
- Overview
- Features
- Quick Start
- Default Credentials
- Managing User Passwords
- Data Dictionary
- Key Performance Indicators
- Project Architecture
- Deployment
- Security Notes
- Contributing
- License
This dashboard enables water utility managers to monitor, analyze, and optimize water and sanitation service delivery across four African countries. It provides:
- Real-time KPI monitoring with industry benchmarks
- AI-powered insights using Google Gemini
- Multi-currency support (local currencies + USD conversion)
- Role-based access (Admin vs Country Managers)
- Exportable reports in PDF and CSV formats
- Monitor Performance: View key metrics like Non-Revenue Water (NRW), Cost Recovery Ratio, Service Coverage, and more
- Compare Countries: Analyze performance across Uganda, Cameroon, Lesotho, and Malawi
- Identify Issues: Spot underperforming zones, payment risks, and service gaps
- Generate Reports: Export data and insights for stakeholder presentations
- Get AI Insights: Ask the AI assistant questions about your data
| Domain | Description | Key Metrics |
|---|---|---|
| 📊 Overview | High-level KPI scorecard | 10 summary KPIs with benchmarks |
| 🏭 Production | Water production operations | Production volume, Service hours, NRW |
| 🚰 Service | Service quality metrics | Water quality, Complaints, Metering |
| 🌍 Access | Coverage and equity | JMP ladder, Zone coverage gaps |
| 💰 Finance | Financial sustainability | OCCR, Collection efficiency, Payment risk |
| 📋 Reports | Export and analysis | PDF/CSV exports, Custom reports |
- AI Data Assistant: Chat interface for data questions
- Automated Insights: AI-generated analysis per domain
- Smart Recommendations: Actionable suggestions based on KPIs
- Operating Cost Coverage Ratio (OCCR)
- Revenue collection efficiency
- Financial waterfall analysis
- Customer payment behavior by zone
- Payment risk dashboard (High/Medium/Low Risk customers)
- Commercial vs. Physical NRW breakdown
- Python 3.8 or higher
- pip (Python package manager)
- Google Gemini API key (optional, for AI features)
# 1. Clone the repository
git clone <repository-url>
cd DASHADI
# 2. Create virtual environment
python -m venv .venv
# On macOS/Linux:
source .venv/bin/activate
# On Windows:
.venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Configure secrets (see Configuration section)
# 5. Run the dashboard
streamlit run app.pyThe dashboard will open in your default web browser at http://localhost:8501
- Copy the secrets template:
cp .streamlit/secrets.toml.example .streamlit/secrets.toml- Edit
.streamlit/secrets.tomlwith your values:GEMINI_API_KEY = "your_actual_api_key"
Ensure all required CSV files are in the Data/ directory:
Data/
├── production.csv
├── billing.csv # 720K+ customer records
├── w_service.csv
├── s_service.csv
├── w_access.csv
├── s_access.csv
├── all_fin_service.csv
└── all_national.csv
| Role | Username | Password |
|---|---|---|
| Admin | admin |
admin123 |
| Uganda Manager | uganda_manager |
uganda123 |
| Malawi Manager | malawi_manager |
malawi123 |
| Lesotho Manager | lesotho_manager |
lesotho123 |
| Cameroon Manager | cameroon_manager |
cameroon123 |
User credentials are stored in config/users.yaml with bcrypt-hashed passwords. Here's how to change passwords or add new users:
Run this command in your terminal (make sure your virtual environment is activated):
# Quick one-liner to generate a hashed password
python -c "import streamlit_authenticator as stauth; print(stauth.Hasher.hash('YOUR_NEW_PASSWORD'))"Example:
# Generate hash for password "SecurePass2024"
python -c "import streamlit_authenticator as stauth; print(stauth.Hasher.hash('SecurePass2024'))"
# Output (example - yours will be different):
# $2b$12$xYz123AbCdEfGhIjKlMnOpQrStUvWxYz456789AbCdEfGhIjKlMnEdit config/users.yaml and replace the password hash:
credentials:
usernames:
admin:
name: Administrator
password: $2b$12$YOUR_NEW_HASH_HERE
email: admin@washboard.org
role: admin
country: nullTo add a new user, copy an existing user block and modify it:
new_user:
name: New User Name
password: $2b$12$GENERATED_HASH_HERE
email: newuser@example.com
role: country_manager # or 'admin'
country: Uganda # Set to null for admin access to all countries| Role | Access Level |
|---|---|
admin |
Full access to all countries, can navigate between country dashboards |
country_manager |
Access only to assigned country's data |
| File | Frequency | Granularity | Records |
|---|---|---|---|
production.csv |
Daily | Source | ~36K |
billing.csv |
Monthly | Customer | ~720K |
w_service.csv |
Monthly | Zone | ~1.5K |
s_service.csv |
Monthly | Zone | ~1.5K |
w_access.csv |
Annual | Zone | ~200 |
s_access.csv |
Annual | Zone | ~200 |
all_fin_service.csv |
Monthly | City | ~500 |
all_national.csv |
Annual | National | ~50 |
| Variable | Type | Unit | Description |
|---|---|---|---|
production_m3 |
Float | m³ | Daily water production volume |
service_hours |
Float | hours/day | Hours of water supply per day |
source |
String | - | Water extraction source name |
date_YYMMDD |
Date | YYYY/MM/DD | Production date |
| Variable | Type | Unit | Description |
|---|---|---|---|
households |
Integer | count | Number of households served |
metered |
Float | m³ | Metered water consumption |
total_consumption |
Float | m³ | Total estimated consumption |
tests_conducted_chlorine |
Integer | count | Chlorine tests conducted |
test_passed_chlorine |
Integer | count | Chlorine tests passed |
| Variable | Type | Unit | Description |
|---|---|---|---|
safely_managed |
Float | population | Population with safely managed access |
basic |
Float | population | Population with basic access |
limited |
Float | population | Population with limited access |
unimproved |
Float | population | Population with unimproved access |
popn_total |
Float | thousands | Total zone population |
| Variable | Type | Unit | Description |
|---|---|---|---|
sewer_billed |
Float | local currency | Total amount billed |
sewer_revenue |
Float | local currency | Total revenue collected |
opex |
Float | local currency | Operating expenditure |
complaints |
Integer | count | Customer complaints received |
| Variable | Type | Unit | Description |
|---|---|---|---|
customer_id |
String | - | Unique customer identifier |
consumption_m3 |
Float | m³ | Monthly water consumption |
billed |
Float | local currency | Amount billed |
paid |
Float | local currency | Amount paid |
| KPI | Benchmark | Formula |
|---|---|---|
| Water Coverage | 100% | (Safely Managed + Basic) / Total Population × 100 |
| Non-Revenue Water (NRW) | ≤25% | (Production - Billed) / Production × 100 |
| Cost Recovery Ratio | ≥100% | Revenue / Operating Expenses × 100 |
| Collection Efficiency | ≥95% | Revenue Collected / Total Billed × 100 |
| Service Continuity | 24 hrs | Average service hours per day |
| Water Quality Compliance | ≥95% | Tests Passed / Tests Conducted × 100 |
| Metering Ratio | ≥95% | Metered / Total Consumption × 100 |
| Staff Productivity | ≤7 | Staff Count / Connections × 1000 |
DASHADI/
├── app.py # Main Streamlit application
├── requirements.txt # Python dependencies
├── config/
│ └── users.yaml # User authentication config
├── Data/ # CSV data files (8 files)
├── page_modules/ # Dashboard page components
│ ├── home.py # Landing page
│ ├── overview.py # KPI scorecard + AI chat
│ ├── production.py # Production analytics
│ ├── service.py # Service quality
│ ├── access.py # Coverage analysis
│ ├── finance.py # Financial metrics
│ └── reports.py # Export functionality
├── utils/ # Shared utilities
│ ├── data_loader.py # Data loading + caching
│ ├── kpi_calculator.py # KPI formulas
│ ├── visualizations.py # Chart templates
│ ├── ai_insights.py # Gemini AI integration
│ ├── currency_config.py # Multi-currency support
│ └── theme.py # Light/dark theme
├── assets/ # Static assets (logos)
└── styles/ # Custom CSS
- Frontend Framework: Streamlit 1.28+
- Data Processing: Pandas 2.0+, NumPy 1.24+
- Visualization: Plotly 5.17+
- AI Integration: Google Gemini API
- Authentication: streamlit-authenticator
- Caching: Streamlit's built-in caching (@st.cache_data)
-
Push code to GitHub (ensure secrets are NOT committed)
-
Deploy on Streamlit Cloud:
- Go to share.streamlit.io
- Connect your GitHub repository
- Set main file path:
app.py
-
Configure Secrets in Streamlit Cloud:
- Go to App Settings → Secrets
- Add your secrets in TOML format:
GEMINI_API_KEY = "your_api_key"
| Variable | Required | Description |
|---|---|---|
GEMINI_API_KEY |
Optional | Google Gemini API key for AI features |
- Never commit
.streamlit/secrets.tomlor.envfiles - Rotate API keys if accidentally exposed
- Change default passwords before production
- Use HTTPS in production deployments
This project is licensed under the MIT License - see the LICENSE file for details.
** For better water services in Africa**
Last Updated: December 2025 |Version 1.0.0