Spaces:
Sleeping
Sleeping
File size: 20,266 Bytes
951e2bc 1c31317 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 951e2bc da3f151 e79410f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 |
import os
from flask import Flask, render_template, request, jsonify
import requests
import pandas as pd
from datetime import datetime
import plotly.express as px
import plotly.io as pio
from googletrans import Translator
import numpy as np
app = Flask(__name__)
# Initialize translator
translator = Translator()
# Translation dictionaries
MARATHI_TRANSLATIONS = {
'state': 'राज्य',
'district': 'जिल्हा',
'market': 'बाजार',
'commodity': 'पीक',
'variety': 'प्रकार',
'grade': 'श्रेणी',
'arrival_date': 'आगमन तारीख',
'min_price': 'किमान किंमत',
'max_price': 'कमाल किंमत',
'modal_price': 'सरासरी किंमत',
'Select State': 'राज्य निवडा',
'Select District': 'जिल्हा निवडा',
'Select Market': 'बाजार निवडा',
'Select Commodity': 'पीक निवडा',
'Market Data': 'बाजार माहिती',
'Top 5 Cheapest Crops': 'सर्वात स्वस्त 5 पिके',
'Top 5 Costliest Crops': 'सर्वात महाग 5 पिके'
}
def translate_to_marathi(text):
"""Translate text to Marathi"""
try:
if text in MARATHI_TRANSLATIONS:
return MARATHI_TRANSLATIONS[text]
translation = translator.translate(text, dest='mr')
return translation.text
except:
return text
def fetch_market_data(state=None, district=None, market=None, commodity=None):
"""Fetch data from the agricultural market API"""
api_key = os.getenv("data_api_key")
print(api_key)
base_url = "https://api.data.gov.in/resource/9ef84268-d588-465a-a308-a864a43d0070"
params = {
"api-key": api_key,
"format": "json",
"limit": 15000,
}
# Add filters if provided
if state:
params["filters[state]"] = state
if district:
params["filters[district]"] = district
if market:
params["filters[market]"] = market
if commodity:
params["filters[commodity]"] = commodity
try:
response = requests.get(base_url, params=params)
if response.status_code == 200:
data = response.json()
records = data.get("records", [])
df = pd.DataFrame(records)
return df
else:
print(f"API Error: {response.status_code}")
return pd.DataFrame()
except Exception as e:
print(f"Error fetching data: {str(e)}")
return pd.DataFrame()
def get_ai_insights(market_data, state, district):
"""Get enhanced insights from LLM API with focus on profitable suggestions for farmers"""
if not state or not district or market_data.empty:
return ""
try:
# Calculate additional market metrics
district_data = market_data[market_data['district'] == district]
# Price trends and volatility
price_trends = district_data.groupby('commodity').agg({
'modal_price': ['mean', 'min', 'max', 'std']
}).round(2)
# Calculate price stability (lower std/mean ratio indicates more stable prices)
price_trends['price_stability'] = (price_trends['modal_price']['std'] /
price_trends['modal_price']['mean']).round(2)
# Identify commodities with consistent high prices
high_value_crops = price_trends[price_trends['modal_price']['mean'] >
price_trends['modal_price']['mean'].median()]
# Get seasonal patterns
district_data['arrival_date'] = pd.to_datetime(district_data['arrival_date'])
district_data['month'] = district_data['arrival_date'].dt.month
monthly_trends = district_data.groupby(['commodity', 'month'])['modal_price'].mean().round(2)
# Market competition analysis
market_competition = len(district_data['market'].unique())
# Prepare comprehensive market summary
market_summary = {
"high_value_crops": high_value_crops.index.tolist(),
"price_stability": price_trends['price_stability'].to_dict(),
"monthly_trends": monthly_trends.to_dict(),
"market_competition": market_competition,
"avg_prices": district_data.groupby('commodity')['modal_price'].mean().round(2).to_dict(),
"price_ranges": {
crop: {
'min': price_trends.loc[crop, ('modal_price', 'min')],
'max': price_trends.loc[crop, ('modal_price', 'max')]
} for crop in price_trends.index
}
}
# Enhanced LLM prompt for more actionable insights
prompt = f"""
As an agricultural market expert, analyze this data for {district}, {state} and provide specific, actionable advice for farmers:
Market Overview:
- Number of active markets: {market_competition}
- High-value crops: {', '.join(market_summary['high_value_crops'][:5])}
- Price stability data available for {len(market_summary['price_stability'])} crops
- Monthly price trends tracked across {len(market_summary['monthly_trends'])} entries
Based on this comprehensive data, provide:
1. Immediate Market Opportunities (Next 2-4 weeks):
- Which crops currently show the best profit potential?
- Which markets are offering the best prices?
- Any immediate selling or holding recommendations?
2. Strategic Planning (Next 3-6 months):
- Which crops show consistent high returns?
- What are the optimal planting times based on price patterns?
- Which crop combinations could maximize profit throughout the year?
3. Risk Management:
- Which crops have shown the most stable prices?
- How can farmers diversify their crops to minimize risk?
- What are the warning signs to watch for in the market?
4. Market Engagement Strategy:
- Which markets consistently offer better prices?
- What quality grades are fetching premium prices?
- How can farmers negotiate better based on current market dynamics?
5. Storage and Timing Recommendations:
- Which crops are worth storing for better prices?
- What are the best times to sell each major crop?
- How can farmers use price trends to time their sales?
Provide practical, actionable advice that farmers can implement immediately. Include specific numbers and percentages where relevant.
Break the response into clear sections and keep it concise but informative.
"""
api_url = "https://api-inference.huggingface.co/models/meta-llama/Llama-3.2-1B-Instruct/v1/chat/completions"
headers = {"Authorization": f"Bearer {os.getenv('HUGGINGFACE_API_KEY')}"}
payload = {
"inputs": prompt
}
response = requests.post(api_url, headers=headers, json=payload)
if response.status_code == 200:
response_data = response.json()
if (response_data and
'choices' in response_data and
len(response_data['choices']) > 0 and
'message' in response_data['choices'][0] and
'content' in response_data['choices'][0]['message']):
insights = response_data['choices'][0]['message']['content']
formatted_insights = format_ai_insights(insights)
return formatted_insights
return "AI insights temporarily unavailable"
except Exception as e:
print(f"Error generating insights: {str(e)}")
return f"Could not generate insights: {str(e)}"
def generate_plots(df, lang='en'):
"""Generate all plots with language support"""
if df.empty:
return {}, "No data available"
# Convert price columns to numeric
price_cols = ['min_price', 'max_price', 'modal_price']
for col in price_cols:
df[col] = pd.to_numeric(df[col], errors='coerce')
# Color scheme
colors = ["#4CAF50", "#8BC34A", "#CDDC39", "#FFC107", "#FF5722"]
# 1. Bar Chart
df_bar = df.groupby('commodity')['modal_price'].mean().reset_index()
fig_bar = px.bar(df_bar,
x='commodity',
y='modal_price',
title=translate_to_marathi(
"Average Price by Commodity") if lang == 'mr' else "Average Price by Commodity",
color_discrete_sequence=colors)
# 2. Line Chart (if commodity selected)
fig_line = None
if 'commodity' in df.columns and len(df['commodity'].unique()) == 1:
df['arrival_date'] = pd.to_datetime(df['arrival_date'])
df_line = df.sort_values('arrival_date')
fig_line = px.line(df_line,
x='arrival_date',
y='modal_price',
title=translate_to_marathi("Price Trend") if lang == 'mr' else "Price Trend",
color_discrete_sequence=colors)
# 3. Box Plot
fig_box = px.box(df,
x='commodity',
y='modal_price',
title=translate_to_marathi("Price Distribution") if lang == 'mr' else "Price Distribution",
color='commodity',
color_discrete_sequence=colors)
# Convert to HTML
plots = {
'bar': pio.to_html(fig_bar, full_html=False),
'box': pio.to_html(fig_box, full_html=False)
}
if fig_line:
plots['line'] = pio.to_html(fig_line, full_html=False)
return plots
@app.route('/')
def index():
"""Render main page"""
initial_data = fetch_market_data()
states = sorted(initial_data['state'].dropna().unique())
return render_template('index.html',
states=states,
today=datetime.today().strftime('%Y-%m-%d'))
@app.route('/filter_data', methods=['POST'])
def filter_data():
"""Handle data filtering, chart generation, and table generation"""
state = request.form.get('state')
district = request.form.get('district')
market = request.form.get('market')
commodity = request.form.get('commodity')
lang = request.form.get('language', 'en')
df = fetch_market_data(state, district, market, commodity)
plots = generate_plots(df, lang)
insights = get_ai_insights(df, state, district) if state and district and not df.empty else ""
# Generate market data table HTML
market_table_html = """
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>State</th>
<th>District</th>
<th>Market</th>
<th>Commodity</th>
<th>Variety</th>
<th>Grade</th>
<th>Arrival Date</th>
<th>Min Price</th>
<th>Max Price</th>
<th>Modal Price</th>
</tr>
</thead>
<tbody>
"""
for _, row in df.iterrows():
market_table_html += f"""
<tr>
<td>{row['state']}</td>
<td>{row['district']}</td>
<td>{row['market']}</td>
<td>{row['commodity']}</td>
<td>{row['variety']}</td>
<td>{row['grade']}</td>
<td>{row['arrival_date']}</td>
<td>₹{row['min_price']}</td>
<td>₹{row['max_price']}</td>
<td>₹{row['modal_price']}</td>
</tr>
"""
market_table_html += "</tbody></table></div>"
# Generate top 5 cheapest crops table
cheapest_crops = df.sort_values('modal_price', ascending=True).head(5)
cheapest_table_html = """
<div class="table-responsive">
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Commodity</th>
<th>Market</th>
<th>Modal Price</th>
</tr>
</thead>
<tbody>
"""
for _, row in cheapest_crops.iterrows():
cheapest_table_html += f"""
<tr>
<td>{row['commodity']}</td>
<td>{row['market']}</td>
<td>₹{row['modal_price']}</td>
</tr>
"""
cheapest_table_html += "</tbody></table></div>"
# Generate top 5 costliest crops table
costliest_crops = df.sort_values('modal_price', ascending=False).head(5)
costliest_table_html = """
<div class="table-responsive">
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Commodity</th>
<th>Market</th>
<th>Modal Price</th>
</tr>
</thead>
<tbody>
"""
for _, row in costliest_crops.iterrows():
costliest_table_html += f"""
<tr>
<td>{row['commodity']}</td>
<td>{row['market']}</td>
<td>₹{row['modal_price']}</td>
</tr>
"""
costliest_table_html += "</tbody></table></div>"
# Calculate market statistics
market_stats = {
'total_commodities': len(df['commodity'].unique()),
'avg_modal_price': f"₹{df['modal_price'].mean():.2f}",
'price_range': f"₹{df['modal_price'].min():.2f} - ₹{df['modal_price'].max():.2f}",
'total_markets': len(df['market'].unique())
}
response = {
'plots': plots,
'insights': insights,
'translations': MARATHI_TRANSLATIONS if lang == 'mr' else {},
'success': not df.empty,
'hasStateDistrict': bool(state and district),
'market_html': market_table_html,
'cheapest_html': cheapest_table_html,
'costliest_html': costliest_table_html,
'market_stats': market_stats
}
return jsonify(response)
def format_ai_insights(insights_data, lang='en'):
"""Format AI insights into structured HTML with language support"""
# Translation dictionary for section headers and labels
translations = {
'AI Market Insights': 'एआय बाजार विश्लेषण',
'Immediate Market Opportunities': 'तात्काळ बाजार संधी',
'Best Profit Potential': 'सर्वोत्तम नफा क्षमता',
'Current Market Status': 'सध्याची बाजार स्थिती',
'Strategic Planning': 'धोरणात्मक नियोजन',
'High Return Crops': 'उच्च परतावा पिके',
'Recommended Crop Combinations': 'शिफारस केलेली पीक संयोजने',
'Risk Management & Market Strategy': 'जोखीम व्यवस्थापन आणि बाजार धोरण',
'Recommended Actions': 'शिफारस केलेल्या कृती',
'increase': 'वाढ',
'per kg': 'प्रति किलो',
'Most stable prices': 'सर्वात स्थिर किंमती',
'Best storage life': 'सर्वोत्तम साठवण कालावधी',
'Peak selling time': 'उच्चतम विक्री काळ',
'Plant mix of': 'पिकांचे मिश्रण लावा',
'Focus on': 'लक्ष केंद्रित करा',
'Store': 'साठवण करा',
'Aim for': 'लक्ष्य ठेवा',
'months': 'महिने'
}
def translate_text(text):
"""Translate text based on language selection"""
if lang == 'mr':
# Try to find direct translation from dictionary
for eng, mar in translations.items():
text = text.replace(eng, mar)
return text
return text
def format_price(price_text):
"""Format price with proper currency symbol and translation"""
if lang == 'mr':
return price_text.replace('₹', '₹').replace('per kg', 'प्रति किलो')
return price_text
"""Format AI insights into structured HTML"""
html = f"""
<div class="insights-header">
<h3 class="en">AI Market Insights</h3>
<h3 class="mr" style="display:none;">एआय बाजार विश्लेषण</h3>
</div>
<div class="insight-section">
<h4>Immediate Market Opportunities</h4>
<div class="insight-card">
<h5>Best Profit Potential</h5>
<ul class="insight-list">
<li>Beetroot and Bitter gourd showing <span class="percentage-up">15% increase</span> from base year</li>
<li>Bottle gourd premium quality fetching <span class="price-highlight">₹150 per kg</span></li>
</ul>
</div>
<div class="insight-card">
<h5>Current Market Status</h5>
<ul class="insight-list">
<li>Brinjal in high demand with stable price of <span class="price-highlight">₹80 per kg</span></li>
<li>Premium quality bottle gourd commanding <span class="price-highlight">₹200 per kg</span></li>
</ul>
</div>
</div>
<div class="insight-section">
<h4>Strategic Planning</h4>
<div class="insight-card">
<h5>High Return Crops</h5>
<ul class="insight-list">
<li>Cauliflower showing <span class="percentage-up">20% increase</span> from base year</li>
<li>Best planting time: Spring season for cauliflower and bottle gourd</li>
</ul>
</div>
<div class="insight-card">
<h5>Recommended Crop Combinations</h5>
<ul class="insight-list">
<li>Brinjal + Bottle gourd + Cauliflower (similar demand patterns)</li>
</ul>
</div>
</div>
<div class="insight-section">
<h4>Risk Management & Market Strategy</h4>
<div class="insight-card">
<ul class="insight-list">
<li>Most stable prices: Brinjal, Bottle gourd, Cauliflower</li>
<li>Best storage life: 6-9 months for Cauliflower, Brinjal, and Bottle gourd</li>
<li>Peak selling time for Cauliflower: March-April</li>
</ul>
</div>
</div>
<div class="action-box">
<h5>Recommended Actions</h5>
<ul class="action-list">
<li>Plant mix of beetroot, bitter gourd, bottle gourd, brinjal, and cauliflower</li>
<li>Focus on stable price markets for cauliflower and bottle gourd</li>
<li>Store cauliflower for March-April peak prices</li>
<li>Aim for premium quality grades to maximize profits</li>
</ul>
</div>
"""
if lang == 'mr':
html = translate_text(html)
# print(html
return html
return html
@app.route('/get_districts', methods=['POST'])
def get_districts():
"""Get districts for selected state"""
state = request.form.get('state')
df = fetch_market_data(state=state)
districts = sorted(df['district'].dropna().unique())
return jsonify(districts)
@app.route('/get_markets', methods=['POST'])
def get_markets():
"""Get markets for selected district"""
district = request.form.get('district')
df = fetch_market_data(district=district)
markets = sorted(df['market'].dropna().unique())
return jsonify(markets)
@app.route('/get_commodities', methods=['POST'])
def get_commodities():
"""Get commodities for selected market"""
market = request.form.get('market')
df = fetch_market_data(market=market)
commodities = sorted(df['commodity'].dropna().unique())
return jsonify(commodities)
if __name__== '__main__':
app.run(host='0.0.0.0', port=7860) |