Skip to content
Kanak234Public

About

AI climate early-warning and crop advisory for smallholder farmers

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

33 Commits

Folders and files

Repository files navigation

Fasal Kavach 🌾

AI Climate Early-Warning & Crop Advisory for Smallholder Farmers

Build with AI: Code for Communities (2nd Edition)
Team: Kanak Prabhakar (Lead) β€” Hazaribagh, Jharkhand


What it does

Fasal Kavach watches the weather against the crop a farmer is actually growing. When a risk crosses a threshold, it sends that farmer a specific, spoken instruction in their own language β€” not a generic forecast.

The core design principle: Deterministic agronomic rules decide whether there is a risk. Gemini only phrases it. The AI cannot invent a warning.


Three modes

Fasal Kavach operates in one of three modes depending on your configuration:

  • Cloud Mode (Gemini via Render / Cloud Run):
    • Data: Real-time live weather data from Open-Meteo, evaluated against deterministic agronomic rules.
    • AI Backend: Google Gemini 2.5 Flash via google-genai SDK.
    • Storage: In-memory (on Render) or persistent (with Firestore).
  • Local Mode (Ollama on Laptop):
    • Data: Real-time live weather data, evaluated against deterministic agronomic rules.
    • AI Backend: Local Ollama server (USE_OLLAMA=true) running Gemma2 or another local LLM for offline AI execution.
    • Storage: In-memory or Firestore.
  • Demo Mode (In-browser Mock):
    • Data: Simulated static data returned by the client fallback.
    • AI Backend: None (mocked local advisories).
    • UI Indicator: Explicitly labeled at the top of every screen with an amber warning banner: Demo data β€” backend not connected.

Quick start (under 10 minutes)

git clone https://github.com/Kanak234/fasal-kavach.git
cd fasal-kavach
cp .env.example .env          # backend
cp .env.example web/.env.local # frontend
# Paste your keys into both

First time? Read FIREBASE_SETUP.md first β€” fifteen minutes in the Firebase console, no code. Without it the app runs on in-memory storage and forgets everything on restart.

You can skip Firebase entirely and still run the rules engine:

USE_FIRESTORE=false DEMO_MODE=true uvicorn main:app --reload --port 8080

Backend

cd api
python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --port 8080
# β†’ http://localhost:8080/docs

Frontend (separate terminal)

cd web
npm install
npm run dev
# β†’ http://localhost:3000

Run tests

cd api && pytest -q      # 88 tests

Check storage is real β€” do this before every demo

curl http://localhost:8080/internal/status
# {"backend": "firestore", "persistent": true, "farms_stored": 12}

If it reports "backend": "memory", Firestore did not connect and your data will disappear on restart. The startup log prints the reason.

Seed the demo farms

curl -X POST http://localhost:8080/internal/seed

Twelve synthetic farms from data/seed/demo_farms.json. The farms are invented; the weather they are evaluated against is fetched live from Open-Meteo and is not.

Trigger ingest (generate advisories)

curl -X POST http://localhost:8080/internal/ingest

Watch template_fallbacks in the response. If it is high, GEMINI_API_KEY is missing or rate limited β€” the app still works, which is the point of the fallback ladder, but know which path your demo is on.

Lint

ruff check .
python3 scripts/check_locale_keys.py

How farmer data is protected

A judge will ask this. The short answer:

  1. Farmers sign in with Google Sign-In (Firebase Auth).
  2. Every API call carries a signed ID token, verified server-side in api/auth.py against Google's public keys. It cannot be forged.
  3. Every farm-scoped read checks ownership. One farmer cannot read another's advisories β€” test_api_flow.py proves it.
  4. firestore.rules enforces the same thing for any direct browser access to the database.
  5. Data lives in Firestore, asia-south1 (Mumbai) β€” on Indian infrastructure.
  6. The district summary endpoint returns counts only. No farm ids, no names, nothing identifying an individual.

DEMO_MODE=true accepts unauthenticated calls as demo_user so a live audience can tap through without waiting for Google sign-in. It is a labelled environment flag, not a hidden bypass. Set it to false for anything with real farmers in it.


Architecture

                       β”Œβ”€β”€β”€ (Backend Connected) ───► FastAPI (Render / Cloud Run)
                       β”‚                              β”œβ”€β”€β”€ AI: Gemini API (Cloud)
                       β”‚                              β”œβ”€β”€β”€ AI: Local Ollama (Laptop)
                       β”‚                              └─── Database: Firestore / In-memory
Next.js PWA ────────────
                       β”‚
                       └─── (Backend Offline) ─────► In-browser Mock Fallback (Demo Mode)
                                                      └─── Warning Banner Active

Rules decide. AI communicates.


Tech stack

Layer Choice
Frontend Next.js 14, TailwindCSS, Firebase Auth
Backend FastAPI (Python 3.11), Cloud Run
Database Cloud Firestore
AI Gemini 2.5 Flash OR Local Ollama (Gemma2, Gemma:2b, etc.)
Scheduling Cloud Scheduler
Preprocessing C++20 CLI tool (offline, not in request path)

Demo path (Section 5.1)

  1. Open the public URL (Note: If the backend is not yet deployed or is offline, the app will show a prominent amber warning banner indicating simulated demo mode).
  2. Log in (or use Demo Farm shortcut)
  3. Create a farm: crop = paddy, sowing = 15 July, area = 1.2 ha
  4. See a live alert generated from real forecast data
  5. Tap the speaker and hear it read aloud in Hindi
  6. Tap "Kya hua?" and see the exact rainfall/temperature numbers
  7. Change the crop to maize β€” the advisory changes accordingly (this is the key step)

Demo district

Hazaribagh, Jharkhand β€” 4 grid cells at 0.25Β° resolution, 4 crops (paddy, maize, wheat, tomato), Hindi and English at Tier 1.


Environment variables

Copy .env.example to .env and fill in:

GEMINI_API_KEY=...
USE_OLLAMA=false
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=gemma2
GOOGLE_CLOUD_PROJECT=fasal-kavach
INTERNAL_TOKEN=...
NEXT_PUBLIC_API_BASE=http://localhost:8080
NEXT_PUBLIC_FIREBASE_*=...  (from Firebase console)

Never commit .env or any key file.

Note: During production deployment, replace NEXT_PUBLIC_API_BASE=RENDER_URL_HERE in web/.env.production with your actual Render backend URL before running npm run build and firebase deploy.


Repository structure

fasal-kavach/
β”œβ”€β”€ api/                 # FastAPI backend (Kanak)
β”‚   β”œβ”€β”€ main.py
β”‚   β”œβ”€β”€ routers/         # farms, advisories, ask, internal
β”‚   β”œβ”€β”€ rules/           # engine, definitions, templates, crop_calendar
β”‚   β”œβ”€β”€ ai/              # Gemini client, cache
β”‚   β”œβ”€β”€ ingest/          # Open-Meteo fetch, job runner
β”‚   β”œβ”€β”€ models/          # Pydantic canonical models
β”‚   └── tests/           # pytest, 100% rule coverage
β”œβ”€β”€ web/                 # Next.js PWA (Member 2)
β”‚   └── src/
β”‚       β”œβ”€β”€ app/         # 6 screens
β”‚       └── lib/         # api.ts, tts.ts, i18n.ts, firebase.ts
β”œβ”€β”€ tools/preprocess/    # C++20 offline baseline tool
β”œβ”€β”€ data/                # crop_calendar.csv, districts.json
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ firestore.rules
└── .github/workflows/ci.yml

Testing

cd api && pytest -q --tb=short
# Expected: all rules pass, calendar edge cases pass, AI validation pass

Deployment

See docs/BUILD_SPEC.docx Section 29 for the full runbook.

# Backend β†’ Cloud Run
gcloud run deploy fasal-kavach-api --source api/ --region asia-south1

# Frontend β†’ Firebase Hosting
cd web && npm run build && firebase deploy --only hosting

Data provenance

See data/README.md for source, licence, and transformation notes for every data file.


Honest claims

  • Working end-to-end prototype for one district, four crops
  • Seeded with real weather data from Open-Meteo (when backend is connected)
  • Rules engine is fully unit-tested with boundary conditions
  • Gemini output is validated β€” number containment check, no pesticide names
  • Graceful degradation: template fallbacks when AI is unavailable, and automatic transparent transition to in-browser demo/mock fallback with a visible UI warning banner when the backend is disconnected
  • Transparency: In-browser demo mode uses simulated data and does not run the backend rules engine, which is honestly declared to the user via the top warning banner.
  • Not claiming: nationwide scale, field-validated agronomy, ML model training

Section numbers in this repo refer to BUILD_SPEC.docx β€” the single source of truth.

About

AI climate early-warning and crop advisory for smallholder farmers

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages