Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -5,7 +5,7 @@ from google import genai
|
|
5 |
import markdown
|
6 |
import os
|
7 |
|
8 |
-
app = Flask(
|
9 |
|
10 |
api_key = os.getenv('GEMINI_API_KEY')
|
11 |
# Replace with your actual Gemini API key
|
@@ -88,81 +88,15 @@ def get_weather_data():
|
|
88 |
except Exception as e:
|
89 |
return jsonify({"error": str(e)}), 500
|
90 |
|
91 |
-
@app.route('/get_soil_properties', methods=['GET'])
|
92 |
-
def get_soil_properties():
|
93 |
-
"""Fetch soil properties using SoilGrids API and map to user-friendly names."""
|
94 |
-
lat = request.args.get('lat')
|
95 |
-
lon = request.args.get('lon')
|
96 |
-
lat, lon = validate_coordinates(lat, lon)
|
97 |
-
if lat is None or lon is None:
|
98 |
-
return jsonify({"error": "Invalid coordinates"}), 400
|
99 |
-
|
100 |
-
try:
|
101 |
-
prop_url = "https://rest.isric.org/soilgrids/v2.0/properties/query"
|
102 |
-
prop_params = {
|
103 |
-
"lon": str(lon),
|
104 |
-
"lat": str(lat),
|
105 |
-
"property": [
|
106 |
-
"bdod", "cec", "cfvo", "clay", "nitrogen",
|
107 |
-
"ocd", "phh2o", "sand", "silt",
|
108 |
-
"soc", "wv0010", "wv0033", "wv1500"
|
109 |
-
],
|
110 |
-
"depth": "5-15cm",
|
111 |
-
"value": "mean"
|
112 |
-
}
|
113 |
-
headers = {"accept": "application/json"}
|
114 |
-
response = requests.get(prop_url, params=prop_params, headers=headers)
|
115 |
-
response.raise_for_status()
|
116 |
-
prop_data = response.json()
|
117 |
-
|
118 |
-
table_data = []
|
119 |
-
PARAMETER_NAMES = {
|
120 |
-
"bdod": "Bulk Density",
|
121 |
-
"cec": "CEC",
|
122 |
-
"cfvo": "Field Capacity",
|
123 |
-
"clay": "Clay",
|
124 |
-
"nitrogen": "Nitrogen",
|
125 |
-
"ocd": "Organic Carbon Density",
|
126 |
-
"phh2o": "pH",
|
127 |
-
"sand": "Sand",
|
128 |
-
"silt": "Silt",
|
129 |
-
"soc": "Soil Organic Carbon",
|
130 |
-
"wv0010": "Volumetric Water Content (0-10cm)",
|
131 |
-
"wv0033": "Volumetric Water Content (10-33cm)",
|
132 |
-
"wv1500": "Volumetric Water Content (1500)"
|
133 |
-
}
|
134 |
-
for layer in prop_data.get('properties', {}).get('layers', []):
|
135 |
-
parameter = layer.get('name')
|
136 |
-
display_name = PARAMETER_NAMES.get(parameter, parameter)
|
137 |
-
value = layer.get('depths', [{}])[0].get('values', {}).get('mean')
|
138 |
-
if value is None:
|
139 |
-
continue
|
140 |
-
if parameter in ["wv0010", "wv0033", "wv1500"]:
|
141 |
-
final_value = value / 10.0
|
142 |
-
unit = layer.get('unit_measure', {}).get("target_units", "")
|
143 |
-
elif parameter in ["phh2o"]:
|
144 |
-
final_value = value / 10.0
|
145 |
-
unit = layer.get('unit_measure', {}).get("mapped_units", "").replace("*10", "").strip()
|
146 |
-
else:
|
147 |
-
final_value = value
|
148 |
-
unit = layer.get('unit_measure', {}).get("mapped_units", "")
|
149 |
-
table_data.append([display_name, final_value, unit])
|
150 |
-
|
151 |
-
return jsonify({"soil_properties": table_data})
|
152 |
-
except Exception as e:
|
153 |
-
return jsonify({"error": str(e)}), 500
|
154 |
-
|
155 |
def call_gemini_api(input_data):
|
156 |
"""
|
157 |
Enhanced prompt: We request a visually appealing Markdown report WITHOUT
|
158 |
showing raw CSS code blocks. Instead, we want a descriptive layout.
|
159 |
-
|
160 |
NOTE: We instruct the model to produce headings, paragraphs, and a table
|
161 |
in a color-rich, well-spaced manner, but NOT to display raw CSS code.
|
162 |
"""
|
163 |
prompt = f"""
|
164 |
Create a visually appealing, farmer-friendly pest outbreak report in Markdown with the following:
|
165 |
-
|
166 |
1. A large, centered heading: "Pest Outbreak Dashboard Report".
|
167 |
2. A short paragraph indicating location (latitude: {input_data.get('latitude')}, longitude: {input_data.get('longitude')}), location as per lat,long(like just ex dont consider it as hardoced nagpur,india so kike fetch from lat,long) and the crop/farm context.
|
168 |
3. Several subheadings (e.g., "Agricultural Inputs", "Pest Outbreak Analysis", "Best Agricultural Practices", "Insights") with short paragraphs.
|
@@ -183,8 +117,6 @@ Important details from the user:
|
|
183 |
- Current Growth Stage: {input_data.get('growth_stage')}
|
184 |
- Irrigation Frequency: {input_data.get('irrigation_freq')}
|
185 |
- Irrigation Method: {input_data.get('irrigation_method')}
|
186 |
-
- Soil Type: {input_data.get('soil_type')}
|
187 |
-
|
188 |
- Max Temp: {input_data.get('max_temp')}
|
189 |
- Min Temp: {input_data.get('min_temp')}
|
190 |
- Current Temp: {input_data.get('current_temp')}
|
@@ -226,7 +158,6 @@ def predict():
|
|
226 |
background: linear-gradient(120deg, #f7f7f7 0%, #e3f2fd 100%);
|
227 |
font-family: 'Segoe UI', Tahoma, sans-serif;
|
228 |
}}
|
229 |
-
|
230 |
.report-container {{
|
231 |
max-width: 1000px;
|
232 |
margin: 0 auto;
|
@@ -240,7 +171,6 @@ def predict():
|
|
240 |
transform: translateY(-4px);
|
241 |
box-shadow: 0 12px 24px rgba(0,0,0,0.15);
|
242 |
}}
|
243 |
-
|
244 |
/* Gradient heading for H1 */
|
245 |
.report-container h1 {{
|
246 |
text-align: center;
|
@@ -252,7 +182,6 @@ def predict():
|
|
252 |
border-radius: 6px;
|
253 |
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
|
254 |
}}
|
255 |
-
|
256 |
/* Secondary headings (H2, H3) */
|
257 |
.report-container h2,
|
258 |
.report-container h3 {{
|
@@ -261,7 +190,6 @@ def predict():
|
|
261 |
color: #2c3e50;
|
262 |
text-align: left;
|
263 |
}}
|
264 |
-
|
265 |
/* Paragraphs */
|
266 |
.report-container p {{
|
267 |
margin-bottom: 1rem;
|
@@ -269,7 +197,6 @@ def predict():
|
|
269 |
text-align: justify;
|
270 |
line-height: 1.6;
|
271 |
}}
|
272 |
-
|
273 |
/* Lists */
|
274 |
.report-container ul,
|
275 |
.report-container ol {{
|
@@ -277,7 +204,6 @@ def predict():
|
|
277 |
margin-bottom: 1rem;
|
278 |
color: #555555;
|
279 |
}}
|
280 |
-
|
281 |
/* Table styling */
|
282 |
.report-container table {{
|
283 |
width: 100%;
|
@@ -298,7 +224,6 @@ def predict():
|
|
298 |
.report-container tbody tr:hover {{
|
299 |
background-color: #f9f9f9;
|
300 |
}}
|
301 |
-
|
302 |
/* Responsive table for smaller screens */
|
303 |
@media (max-width: 768px) {{
|
304 |
.report-container table,
|
@@ -338,5 +263,5 @@ def predict():
|
|
338 |
return Response(html_output, mimetype="text/html")
|
339 |
|
340 |
|
341 |
-
if
|
342 |
app.run(debug=True)
|
|
|
5 |
import markdown
|
6 |
import os
|
7 |
|
8 |
+
app = Flask(_name_)
|
9 |
|
10 |
api_key = os.getenv('GEMINI_API_KEY')
|
11 |
# Replace with your actual Gemini API key
|
|
|
88 |
except Exception as e:
|
89 |
return jsonify({"error": str(e)}), 500
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
def call_gemini_api(input_data):
|
92 |
"""
|
93 |
Enhanced prompt: We request a visually appealing Markdown report WITHOUT
|
94 |
showing raw CSS code blocks. Instead, we want a descriptive layout.
|
|
|
95 |
NOTE: We instruct the model to produce headings, paragraphs, and a table
|
96 |
in a color-rich, well-spaced manner, but NOT to display raw CSS code.
|
97 |
"""
|
98 |
prompt = f"""
|
99 |
Create a visually appealing, farmer-friendly pest outbreak report in Markdown with the following:
|
|
|
100 |
1. A large, centered heading: "Pest Outbreak Dashboard Report".
|
101 |
2. A short paragraph indicating location (latitude: {input_data.get('latitude')}, longitude: {input_data.get('longitude')}), location as per lat,long(like just ex dont consider it as hardoced nagpur,india so kike fetch from lat,long) and the crop/farm context.
|
102 |
3. Several subheadings (e.g., "Agricultural Inputs", "Pest Outbreak Analysis", "Best Agricultural Practices", "Insights") with short paragraphs.
|
|
|
117 |
- Current Growth Stage: {input_data.get('growth_stage')}
|
118 |
- Irrigation Frequency: {input_data.get('irrigation_freq')}
|
119 |
- Irrigation Method: {input_data.get('irrigation_method')}
|
|
|
|
|
120 |
- Max Temp: {input_data.get('max_temp')}
|
121 |
- Min Temp: {input_data.get('min_temp')}
|
122 |
- Current Temp: {input_data.get('current_temp')}
|
|
|
158 |
background: linear-gradient(120deg, #f7f7f7 0%, #e3f2fd 100%);
|
159 |
font-family: 'Segoe UI', Tahoma, sans-serif;
|
160 |
}}
|
|
|
161 |
.report-container {{
|
162 |
max-width: 1000px;
|
163 |
margin: 0 auto;
|
|
|
171 |
transform: translateY(-4px);
|
172 |
box-shadow: 0 12px 24px rgba(0,0,0,0.15);
|
173 |
}}
|
|
|
174 |
/* Gradient heading for H1 */
|
175 |
.report-container h1 {{
|
176 |
text-align: center;
|
|
|
182 |
border-radius: 6px;
|
183 |
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
|
184 |
}}
|
|
|
185 |
/* Secondary headings (H2, H3) */
|
186 |
.report-container h2,
|
187 |
.report-container h3 {{
|
|
|
190 |
color: #2c3e50;
|
191 |
text-align: left;
|
192 |
}}
|
|
|
193 |
/* Paragraphs */
|
194 |
.report-container p {{
|
195 |
margin-bottom: 1rem;
|
|
|
197 |
text-align: justify;
|
198 |
line-height: 1.6;
|
199 |
}}
|
|
|
200 |
/* Lists */
|
201 |
.report-container ul,
|
202 |
.report-container ol {{
|
|
|
204 |
margin-bottom: 1rem;
|
205 |
color: #555555;
|
206 |
}}
|
|
|
207 |
/* Table styling */
|
208 |
.report-container table {{
|
209 |
width: 100%;
|
|
|
224 |
.report-container tbody tr:hover {{
|
225 |
background-color: #f9f9f9;
|
226 |
}}
|
|
|
227 |
/* Responsive table for smaller screens */
|
228 |
@media (max-width: 768px) {{
|
229 |
.report-container table,
|
|
|
263 |
return Response(html_output, mimetype="text/html")
|
264 |
|
265 |
|
266 |
+
if _name_ == '_main_':
|
267 |
app.run(debug=True)
|