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 = """
""" for _, row in df.iterrows(): market_table_html += f""" """ market_table_html += "
State District Market Commodity Variety Grade Arrival Date Min Price Max Price Modal Price
{row['state']} {row['district']} {row['market']} {row['commodity']} {row['variety']} {row['grade']} {row['arrival_date']} ₹{row['min_price']} ₹{row['max_price']} ₹{row['modal_price']}
" # Generate top 5 cheapest crops table cheapest_crops = df.sort_values('modal_price', ascending=True).head(5) cheapest_table_html = """
""" for _, row in cheapest_crops.iterrows(): cheapest_table_html += f""" """ cheapest_table_html += "
Commodity Market Modal Price
{row['commodity']} {row['market']} ₹{row['modal_price']}
" # Generate top 5 costliest crops table costliest_crops = df.sort_values('modal_price', ascending=False).head(5) costliest_table_html = """
""" for _, row in costliest_crops.iterrows(): costliest_table_html += f""" """ costliest_table_html += "
Commodity Market Modal Price
{row['commodity']} {row['market']} ₹{row['modal_price']}
" # 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"""

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
""" 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)