Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -7,6 +7,7 @@ import plotly.express as px
|
|
7 |
import plotly.io as pio
|
8 |
import numpy as np
|
9 |
import dotenv
|
|
|
10 |
|
11 |
dotenv.load_dotenv()
|
12 |
|
@@ -18,7 +19,7 @@ def fetch_market_data(state=None, district=None, market=None, commodity=None):
|
|
18 |
Filters (state, district, market, commodity) are applied manually on CSV data.
|
19 |
"""
|
20 |
api_key = "579b464db66ec23bdd000001189bbb99e979428764bdbe8fdd44ebb7"
|
21 |
-
base_url = "https://api.data.gov.in/resource/9ef84268-d588-465a-a308-
|
22 |
|
23 |
params = {
|
24 |
"api-key": api_key,
|
@@ -91,26 +92,43 @@ def fetch_market_data(state=None, district=None, market=None, commodity=None):
|
|
91 |
|
92 |
return df
|
93 |
|
94 |
-
def get_ai_insights(market_data, state, district):
|
95 |
-
"""Get enhanced insights from
|
|
|
96 |
Returns dynamic insights only. If something goes wrong, returns an empty string.
|
97 |
"""
|
98 |
if not state or not district or market_data.empty:
|
99 |
return ""
|
100 |
|
101 |
try:
|
|
|
102 |
district_data = market_data[market_data['district'] == district]
|
103 |
if district_data.empty:
|
104 |
return ""
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
price_trends = district_data.groupby('commodity').agg({
|
107 |
'modal_price': ['mean', 'min', 'max', 'std']
|
108 |
}).round(2)
|
109 |
|
110 |
-
# Using
|
111 |
-
api_key = os.
|
112 |
if not api_key:
|
113 |
-
print("Warning:
|
114 |
return ""
|
115 |
|
116 |
price_trends['price_stability'] = (price_trends['modal_price']['std'] /
|
@@ -123,46 +141,110 @@ def get_ai_insights(market_data, state, district):
|
|
123 |
market_competition = len(district_data['market'].unique())
|
124 |
top_commodities = district_data.groupby('commodity')['modal_price'].mean().nlargest(5).index.tolist()
|
125 |
|
126 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
prompt = f"""
|
128 |
-
Analyze the following market data for {district}, {state}
|
|
|
|
|
129 |
- Active markets: {market_competition}
|
130 |
- Top crops: {', '.join(top_commodities[:5])}
|
131 |
- Data from {len(price_trends.index)} crops and {len(monthly_trends)} monthly entries.
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
Provide structured insights with clear sections. Use this exact format with bullet points:
|
134 |
|
135 |
Crop Profitability Analysis:
|
136 |
-
* [First insight about profitable crops]
|
137 |
* [Second insight]
|
138 |
|
139 |
Market Price Analysis:
|
140 |
-
* [First insight about markets]
|
141 |
* [Second insight]
|
142 |
|
143 |
-
Recommendations:
|
144 |
* [Action item 1]
|
145 |
* [Action item 2]
|
146 |
"""
|
147 |
|
148 |
-
api_url = "https://
|
149 |
-
headers = {"
|
|
|
150 |
payload = {
|
151 |
-
"
|
152 |
-
{
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
}
|
155 |
|
156 |
-
response = requests.post(
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
if response.status_code == 200:
|
158 |
response_data = response.json()
|
159 |
-
if
|
160 |
-
|
161 |
-
|
162 |
-
insights =
|
163 |
return format_ai_insights(insights)
|
164 |
-
print(f"API Response issue: {response.
|
165 |
-
|
|
|
|
|
|
|
166 |
|
167 |
except Exception as e:
|
168 |
print(f"Error generating insights: {str(e)}")
|
@@ -294,10 +376,12 @@ def filter_data():
|
|
294 |
district = request.form.get('district')
|
295 |
market = request.form.get('market')
|
296 |
commodity = request.form.get('commodity')
|
|
|
297 |
|
298 |
df = fetch_market_data(state, district, market, commodity)
|
299 |
plots = generate_plots(df)
|
300 |
-
|
|
|
301 |
|
302 |
market_table_html = """
|
303 |
<div class="table-responsive">
|
@@ -427,4 +511,4 @@ def get_commodities():
|
|
427 |
|
428 |
if __name__ == '__main__':
|
429 |
app.run(debug=True, host='0.0.0.0', port=7860)
|
430 |
-
pio.templates.default = "plotly_white"
|
|
|
7 |
import plotly.io as pio
|
8 |
import numpy as np
|
9 |
import dotenv
|
10 |
+
import json
|
11 |
|
12 |
dotenv.load_dotenv()
|
13 |
|
|
|
19 |
Filters (state, district, market, commodity) are applied manually on CSV data.
|
20 |
"""
|
21 |
api_key = "579b464db66ec23bdd000001189bbb99e979428764bdbe8fdd44ebb7"
|
22 |
+
base_url = "https://api.data.gov.in/resource/9ef84268-d588-465a-a308-a864a43d007"
|
23 |
|
24 |
params = {
|
25 |
"api-key": api_key,
|
|
|
92 |
|
93 |
return df
|
94 |
|
95 |
+
def get_ai_insights(market_data, state, district, market=None, commodity=None, language="English"):
|
96 |
+
"""Get enhanced insights from Gemini API with focus on profitable suggestions for farmers.
|
97 |
+
Supports multiple languages through the prompt.
|
98 |
Returns dynamic insights only. If something goes wrong, returns an empty string.
|
99 |
"""
|
100 |
if not state or not district or market_data.empty:
|
101 |
return ""
|
102 |
|
103 |
try:
|
104 |
+
# Filter data based on provided parameters
|
105 |
district_data = market_data[market_data['district'] == district]
|
106 |
if district_data.empty:
|
107 |
return ""
|
108 |
|
109 |
+
# Apply market filter if provided
|
110 |
+
if market and not market_data[market_data['market'] == market].empty:
|
111 |
+
market_specific = True
|
112 |
+
district_data = district_data[district_data['market'] == market]
|
113 |
+
else:
|
114 |
+
market_specific = False
|
115 |
+
|
116 |
+
# Apply commodity filter if provided
|
117 |
+
if commodity and not market_data[market_data['commodity'] == commodity].empty:
|
118 |
+
commodity_specific = True
|
119 |
+
district_data = district_data[district_data['commodity'] == commodity]
|
120 |
+
else:
|
121 |
+
commodity_specific = False
|
122 |
+
|
123 |
+
# Calculate price trends
|
124 |
price_trends = district_data.groupby('commodity').agg({
|
125 |
'modal_price': ['mean', 'min', 'max', 'std']
|
126 |
}).round(2)
|
127 |
|
128 |
+
# Using environment variable for Gemini API key
|
129 |
+
api_key = os.environ.get('GEMINI_API_KEY')
|
130 |
if not api_key:
|
131 |
+
print("Warning: Gemini API key not set")
|
132 |
return ""
|
133 |
|
134 |
price_trends['price_stability'] = (price_trends['modal_price']['std'] /
|
|
|
141 |
market_competition = len(district_data['market'].unique())
|
142 |
top_commodities = district_data.groupby('commodity')['modal_price'].mean().nlargest(5).index.tolist()
|
143 |
|
144 |
+
# Get min and max prices for key commodities
|
145 |
+
price_range_info = {}
|
146 |
+
for commodity in top_commodities[:3]:
|
147 |
+
comm_data = district_data[district_data['commodity'] == commodity]
|
148 |
+
if not comm_data.empty:
|
149 |
+
price_range_info[commodity] = {
|
150 |
+
'min': comm_data['modal_price'].min(),
|
151 |
+
'max': comm_data['modal_price'].max(),
|
152 |
+
'avg': comm_data['modal_price'].mean()
|
153 |
+
}
|
154 |
+
|
155 |
+
# Calculate market-specific metrics if market is selected
|
156 |
+
market_details = ""
|
157 |
+
if market_specific:
|
158 |
+
market_details = f"""
|
159 |
+
Market-specific information for {market}:
|
160 |
+
- Number of commodities: {len(district_data['commodity'].unique())}
|
161 |
+
- Most expensive commodity: {district_data.groupby('commodity')['modal_price'].mean().idxmax()}
|
162 |
+
- Cheapest commodity: {district_data.groupby('commodity')['modal_price'].mean().idxmin()}
|
163 |
+
"""
|
164 |
+
|
165 |
+
# Commodity-specific details if commodity is selected
|
166 |
+
commodity_details = ""
|
167 |
+
if commodity_specific:
|
168 |
+
commodity_data = district_data[district_data['commodity'] == commodity]
|
169 |
+
best_market = commodity_data.loc[commodity_data['modal_price'].idxmin()]['market']
|
170 |
+
worst_market = commodity_data.loc[commodity_data['modal_price'].idxmax()]['market']
|
171 |
+
|
172 |
+
commodity_details = f"""
|
173 |
+
Commodity-specific information for {commodity}:
|
174 |
+
- Best market to buy (lowest price): {best_market}
|
175 |
+
- Highest priced market: {worst_market}
|
176 |
+
- Price variance across markets: {commodity_data['modal_price'].std().round(2)}
|
177 |
+
"""
|
178 |
+
|
179 |
+
# Improved prompt for better structured output with language support
|
180 |
prompt = f"""
|
181 |
+
Analyze the following agricultural market data for {district}, {state} and provide insights in {language} language.
|
182 |
+
|
183 |
+
Market data:
|
184 |
- Active markets: {market_competition}
|
185 |
- Top crops: {', '.join(top_commodities[:5])}
|
186 |
- Data from {len(price_trends.index)} crops and {len(monthly_trends)} monthly entries.
|
187 |
+
|
188 |
+
Price information:
|
189 |
+
{json.dumps(price_range_info, indent=2)}
|
190 |
+
|
191 |
+
{market_details}
|
192 |
+
{commodity_details}
|
193 |
+
|
194 |
+
Analyze this data and provide insights about crop market trends and profitability.
|
195 |
+
Include specific numbers from the data about prices.
|
196 |
+
|
197 |
Provide structured insights with clear sections. Use this exact format with bullet points:
|
198 |
|
199 |
Crop Profitability Analysis:
|
200 |
+
* [First insight about profitable crops with specific prices mentioned]
|
201 |
* [Second insight]
|
202 |
|
203 |
Market Price Analysis:
|
204 |
+
* [First insight about markets with specific price ranges]
|
205 |
* [Second insight]
|
206 |
|
207 |
+
Recommendations for Farmers:
|
208 |
* [Action item 1]
|
209 |
* [Action item 2]
|
210 |
"""
|
211 |
|
212 |
+
api_url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent"
|
213 |
+
headers = {"Content-Type": "application/json"}
|
214 |
+
|
215 |
payload = {
|
216 |
+
"contents": [
|
217 |
+
{
|
218 |
+
"parts": [
|
219 |
+
{"text": prompt}
|
220 |
+
]
|
221 |
+
}
|
222 |
+
],
|
223 |
+
"generationConfig": {
|
224 |
+
"temperature": 0.4,
|
225 |
+
"maxOutputTokens": 1024
|
226 |
+
}
|
227 |
}
|
228 |
|
229 |
+
response = requests.post(
|
230 |
+
f"{api_url}?key={api_key}",
|
231 |
+
headers=headers,
|
232 |
+
json=payload,
|
233 |
+
timeout=20
|
234 |
+
)
|
235 |
+
|
236 |
if response.status_code == 200:
|
237 |
response_data = response.json()
|
238 |
+
if 'candidates' in response_data and len(response_data['candidates']) > 0:
|
239 |
+
content = response_data['candidates'][0]['content']
|
240 |
+
if 'parts' in content and len(content['parts']) > 0:
|
241 |
+
insights = content['parts'][0]['text']
|
242 |
return format_ai_insights(insights)
|
243 |
+
print(f"API Response issue: {response.text[:100]}")
|
244 |
+
else:
|
245 |
+
print(f"Gemini API Error: {response.status_code} - {response.text[:100]}")
|
246 |
+
|
247 |
+
return ""
|
248 |
|
249 |
except Exception as e:
|
250 |
print(f"Error generating insights: {str(e)}")
|
|
|
376 |
district = request.form.get('district')
|
377 |
market = request.form.get('market')
|
378 |
commodity = request.form.get('commodity')
|
379 |
+
language = request.form.get('language', 'English') # Default to English
|
380 |
|
381 |
df = fetch_market_data(state, district, market, commodity)
|
382 |
plots = generate_plots(df)
|
383 |
+
# Pass market and commodity to get_ai_insights
|
384 |
+
insights = get_ai_insights(df, state, district, market, commodity, language) if state and district and not df.empty else ""
|
385 |
|
386 |
market_table_html = """
|
387 |
<div class="table-responsive">
|
|
|
511 |
|
512 |
if __name__ == '__main__':
|
513 |
app.run(debug=True, host='0.0.0.0', port=7860)
|
514 |
+
pio.templates.default = "plotly_white"
|