FarmGuard-AI is a data-driven decision-support system designed to empower small-scale farmers in Kenya. By merging historical climate trends with real-time market volatility, the system provides automated alerts for drought, heat stress, and floods, alongside AI-powered price forecasts for staple crops.
# FarmGuard AI 🌾
**Explore the Live Dashboard:** Click here to view the active platform
(
# FarmGuard AI — Full Architecture
## Directory structure
```
farmguard_v2/
├── api/ # Component 1: FastAPI backend
│ ├── main.py # /predict, /health, /webhook/whatsapp, /api/counties,
│ │ # /api/predict/all, /api/history, /refresh
│ ├── schemas.py # Pydantic request/response models
│ ├── model_pipeline.py # training + prediction for all 47 counties
│ ├── kenya_counties.py # 47 counties: lat/lon + agro-ecological zone + soil profiles
│ ├── requirements.txt
│ └── models/ # trained .joblib bundles, one per county
├── dashboard/ # Component 2: Streamlit live dashboard
│ ├── app.py # dark-green themed UI, calls the API over HTTP
│ ├── assets/ # drop banner.png / logo.png here (optional)
│ └── requirements.txt
├── whatsapp/ # Component 3: WhatsApp bot logic
│ └── handler.py # message parsing + reply building, provider-agnostic
├── Dockerfile.api
├── Dockerfile.dashboard
└── README.md (this file)
```
The three components are genuinely separable: `dashboard/app.py` only ever
talks to the API over HTTP (never imports model code directly), and
`whatsapp/handler.py` contains pure message-in/reply-out logic with no
Twilio-specific code, so swapping to Meta's WhatsApp Cloud API directly
later only touches `api/main.py`'s webhook glue, not the bot's brain.
## All 47 Kenyan counties
`api/kenya_counties.py` lists every county with a centroid lat/lon and one
of 7 agro-ecological zones (central highlands, lake basin, rift valley,
eastern semi-arid, coast, arid north, southern rangelands). Soil profiles
are assigned per zone, not per county — that's a genuine simplification,
documented in that file, and the honest reason two counties in the same
zone show the same soil type. Swap `ZONE …