|
|
from flask import Flask, render_template, request
|
|
|
from markupsafe import Markup
|
|
|
import google.generativeai as genai
|
|
|
from openai import OpenAI
|
|
|
import os
|
|
|
import dotenv
|
|
|
|
|
|
dotenv.load_dotenv()
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
|
GEMINI_API_KEY = os.getenv('GEMINI_API_KEY')
|
|
|
NVIDIA_API_KEY = os.getenv('NVIDIA_API_KEY')
|
|
|
|
|
|
|
|
|
if GEMINI_API_KEY:
|
|
|
genai.configure(api_key=GEMINI_API_KEY)
|
|
|
|
|
|
|
|
|
nvidia_client = None
|
|
|
if NVIDIA_API_KEY:
|
|
|
nvidia_client = OpenAI(
|
|
|
base_url="https://integrate.api.nvidia.com/v1",
|
|
|
api_key=NVIDIA_API_KEY
|
|
|
)
|
|
|
|
|
|
def call_llm(prompt):
|
|
|
"""Call LLM with Gemini -> NVIDIA fallback."""
|
|
|
|
|
|
if GEMINI_API_KEY:
|
|
|
for model_name in ["gemini-2.5-flash", "gemini-2.5-flash-lite"]:
|
|
|
try:
|
|
|
print(f" >> Trying Gemini {model_name}...")
|
|
|
model = genai.GenerativeModel(model_name)
|
|
|
response = model.generate_content(prompt)
|
|
|
if response and response.text:
|
|
|
print(f" >> SUCCESS with {model_name}")
|
|
|
return response.text
|
|
|
except Exception as e:
|
|
|
print(f" >> {model_name} failed: {e}")
|
|
|
continue
|
|
|
|
|
|
|
|
|
if nvidia_client:
|
|
|
nvidia_models = ["meta/llama-3.1-405b-instruct", "meta/llama-3.1-70b-instruct", "google/gemma-3-27b-it"]
|
|
|
for model_name in nvidia_models:
|
|
|
try:
|
|
|
print(f" >> Trying NVIDIA {model_name}...")
|
|
|
response = nvidia_client.chat.completions.create(
|
|
|
model=model_name,
|
|
|
messages=[{"role": "user", "content": prompt}],
|
|
|
max_tokens=4096,
|
|
|
temperature=0.3
|
|
|
)
|
|
|
print(f" >> SUCCESS with {model_name}")
|
|
|
return response.choices[0].message.content
|
|
|
except Exception as e:
|
|
|
print(f" >> {model_name} failed: {e}")
|
|
|
continue
|
|
|
|
|
|
return "<p>Error: All AI models failed. Please check API keys.</p>"
|
|
|
|
|
|
|
|
|
@app.route('/', methods=['GET', 'POST'])
|
|
|
def index():
|
|
|
if request.method == 'POST':
|
|
|
|
|
|
location = request.form.get('location')
|
|
|
total_area = request.form.get('total_area')
|
|
|
language = request.form.get('language', 'English')
|
|
|
|
|
|
|
|
|
crop_seasons = request.form.getlist('crop_season')
|
|
|
crop_names = request.form.getlist('crop_name')
|
|
|
crop_areas = request.form.getlist('crop_area')
|
|
|
|
|
|
crops = []
|
|
|
for s, n, a in zip(crop_seasons, crop_names, crop_areas):
|
|
|
if n.strip() and a.strip():
|
|
|
crops.append(f"{s}: {n.strip()} ({a.strip()} acres)")
|
|
|
|
|
|
current_plan = " | ".join(crops)
|
|
|
|
|
|
prompt = f"""
|
|
|
You are an advanced agricultural economist. I will provide the farmer's **Current Annual Crop Cycle**.
|
|
|
Your task is to generate a **3-Year Optimization Plan** and explicitly explain **WHY their current plan is losing money/underperforming** compared to the potential.
|
|
|
|
|
|
**Inputs:**
|
|
|
- Location: {location}
|
|
|
- Total Area: {total_area} acres
|
|
|
- Current Annual Plan: {current_plan}
|
|
|
|
|
|
**OUTPUT FORMAT INSTRUCTIONS:**
|
|
|
Generate ONLY the HTML content inside `<div>` tags. Use the specific CSS classes below.
|
|
|
|
|
|
**Structure & CSS Classes to Use:**
|
|
|
|
|
|
1. **Executive Summary (2 Cards):**
|
|
|
Use `<div class="stats-grid" style="grid-template-columns: 1fr 1fr; max-width: 700px; margin: 0 auto 1.5rem;">` containing:
|
|
|
- Card 1: **Projected Annual Net Profit** (Value in `stat-value`)
|
|
|
- Card 2: **Revenue Increase** (Value in `stat-value` with `color: #1a5d3a`)
|
|
|
|
|
|
2. **GAP ANALYSIS (Why the Loss?):**
|
|
|
Header: `<h3><i class="bi bi-search"></i> Input Strategy Analysis</h3>`
|
|
|
Use `<div class="gap-analysis-card">` (I will add this CSS):
|
|
|
- `<h4><i class="bi bi-exclamation-circle"></i> Inefficiencies Detected in Current Plan:</h4>`
|
|
|
- `<ul>`
|
|
|
- `<li><b>[Factor 1]:</b> [Explanation, e.g., 'Monoculture of Wheat increases pest risk and fertilizer cost by 20%']</li>`
|
|
|
- `<li><b>[Factor 2]:</b> [Explanation, e.g., 'Missing Zaid season leaves 4 months of revenue potential on the table']</li>`
|
|
|
- `<li><b>[Factor 3]:</b> [Explanation]</li>`
|
|
|
- `</ul>`
|
|
|
|
|
|
3. **Annual Financial Breakdown (Single Bar):**
|
|
|
Header: `<h3><i class="bi bi-pie-chart"></i> Projected Financials</h3>`
|
|
|
Use `<div class="breakdown-section">`:
|
|
|
- Title: `<div class="breakdown-title"><span>Breakdown (Avg Annual)</span> <span>Total Rev: [Value]</span></div>`
|
|
|
- Stacked Bar: `<div class="stacked-bar-container">`
|
|
|
- `<div class="bar-cost" style="width: [Cost%]%">Cost [Value]</div>`
|
|
|
- `<div class="bar-profit" style="width: [Profit%]%">Profit [Value]</div>`
|
|
|
- Legend included below.
|
|
|
|
|
|
4. **3-Year Crop Rotation (Vertical Stalk):**
|
|
|
Header: `<h3><i class="bi bi-bezier2"></i> Crop Rotation Journey</h3>`
|
|
|
Use `<div class="growth-timeline">`:
|
|
|
- **For EACH Year (1, 2, 3):**
|
|
|
`<div class="growth-node">`
|
|
|
`<div class="growth-card">`
|
|
|
`<div class="growth-header">`
|
|
|
`<span>Year 1</span>`
|
|
|
`<span>Est. Income: [Value]</span>`
|
|
|
`</div>`
|
|
|
`<table class="annual-table">`
|
|
|
`<thead><tr><th>Season</th><th>Crop</th><th>Exp/Rev/Profit</th></tr></thead>`
|
|
|
`<tbody>`
|
|
|
`<tr>`
|
|
|
`<td><span class="season-badge">Kharif</span></td>`
|
|
|
`<td><b>[Crop Name]</b></td>`
|
|
|
`<td>Exp: [Val]<br>Prof: <b>[Val]</b></td>`
|
|
|
`</tr>`
|
|
|
`<tr>`
|
|
|
`<td><span class="season-badge">Rabi</span></td>`
|
|
|
`<td><b>[Crop Name]</b></td>`
|
|
|
`<td>Exp: [Val]<br>Prof: <b>[Val]</b></td>`
|
|
|
`</tr>`
|
|
|
`<tr>`
|
|
|
`<td><span class="season-badge">Zaid</span></td>`
|
|
|
`<td><b>[Crop Name]</b></td>`
|
|
|
`<td>Exp: [Val]<br>Prof: <b>[Val]</b></td>`
|
|
|
`</tr>`
|
|
|
`</tbody>`
|
|
|
`</table>`
|
|
|
`</div>`
|
|
|
`</div>`
|
|
|
|
|
|
5. **Comparison Table:**
|
|
|
Header: `<h3><i class="bi bi-table"></i> Strategy Comparison</h3>`
|
|
|
Use `<div class="smart-table-container">` with `<table class="smart-table">`.
|
|
|
- Columns: Metric, Current Annual Plan, Proposed (Avg Annual), Change.
|
|
|
- Rows: Gross Revenue, Total Cost, Net Profit.
|
|
|
- **COLOR LOGIC:**
|
|
|
- **Total Cost:** Identify if Cost Increases or Decreases. Mark "Cost Increase" as `<span class="negative">` (Red). Mark "Cost Decrease" as `<span class="positive">` (Green).
|
|
|
- **Net Profit:** Increase = Positive (Green).
|
|
|
|
|
|
**Guidelines:**
|
|
|
- **Language:** {language}
|
|
|
- **REALISM:** Ensure the gap isn't exaggerated. If the current plan is decent, say so. If it's bad, explain EXACTLY why (e.g., pests, soil depletion, unused seasons).
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
print(f"\n[CROP REVENUE] Generating report for {location}...")
|
|
|
result_html = call_llm(prompt)
|
|
|
result_html = result_html.strip()
|
|
|
|
|
|
|
|
|
if result_html.startswith("```html"):
|
|
|
result_html = result_html[7:]
|
|
|
if result_html.startswith("```"):
|
|
|
result_html = result_html[3:]
|
|
|
if result_html.endswith("```"):
|
|
|
result_html = result_html[:-3]
|
|
|
|
|
|
return render_template('index.html', result=Markup(result_html.strip()))
|
|
|
|
|
|
except Exception as e:
|
|
|
error_message = f"Error generating crop strategy: {str(e)}"
|
|
|
return render_template('index.html', error=error_message)
|
|
|
|
|
|
return render_template('index.html')
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
app.run(debug=True, port=5003) |