Spaces:
Sleeping
Sleeping
from flask import Flask, render_template, request, jsonify | |
import requests | |
from google import genai | |
from google.genai import types # for configuration types | |
import markdown | |
import os | |
app = Flask(__name__) | |
# Mapping of SoilGrids parameter codes to descriptive names and explanations | |
PARAM_MAP = { | |
"bdod": ("Bulk Density", "Mass of dry soil per unit volume (cg/cm³)"), | |
"cec": ("Cation Exchange Capacity", "Soil's ability to hold essential nutrients (mmol(c)/kg)"), | |
"cfvo": ("Coarse Fragment Volume", "Volume fraction of coarse fragments in soil (cm³/dm³)"), | |
"clay": ("Clay Content", "Amount of clay in the soil (g/kg)"), | |
"nitrogen": ("Nitrogen Content", "Soil nitrogen levels (cg/kg)"), | |
"ocd": ("Organic Carbon Density", "Organic carbon per unit volume (dg/dm³)"), | |
"ocs": ("Organic Carbon Stock", "Organic carbon per unit mass (dg/kg)"), | |
"phh2o": ("Soil pH", "Acidity or alkalinity of the soil"), | |
"sand": ("Sand Content", "Amount of sand in the soil (g/kg)"), | |
"silt": ("Silt Content", "Amount of silt in the soil (g/kg)"), | |
"soc": ("Soil Organic Carbon", "Concentration of organic carbon in the soil (dg/kg)"), | |
"wv0010": ("Water Content (0-10cm)", "Water content for shallow soil layers (10^-2 cm³/cm³)"), | |
"wv0033": ("Water Content (0-33cm)", "Water content for intermediate soil layers (10^-2 cm³/cm³)"), | |
"wv1500": ("Water Content (1500mm)", "Water content for deep soil layers (10^-2 cm³/cm³)") | |
} | |
def index(): | |
return render_template('index1.html') | |
def get_soil_report(): | |
data = request.get_json() | |
lat = data.get("lat") | |
lon = data.get("lon") | |
if not lat or not lon: | |
return jsonify({"error": "Latitude and Longitude are required"}), 400 | |
headers = {"accept": "application/json"} | |
timeout_val = 10 # seconds | |
# Fetch Soil Classification | |
classification_url = "https://dev-rest.isric.org/soilgrids/v2.0/classification/query" | |
classification_params = { | |
"lon": lon, | |
"lat": lat, | |
"number_classes": "5" | |
} | |
try: | |
class_response = requests.get(classification_url, params=classification_params, | |
headers=headers, timeout=timeout_val) | |
class_response.raise_for_status() | |
class_data = class_response.json() | |
except Exception as e: | |
return jsonify({"error": "Failed to fetch soil classification: " + str(e)}), 500 | |
soil_classification = { | |
"soil_type": class_data.get("wrb_class_name", "Unknown"), | |
"soil_probabilities": class_data.get("wrb_class_probability", []) | |
} | |
# Fetch Soil Properties | |
properties_url = "https://dev-rest.isric.org/soilgrids/v2.0/properties/query" | |
properties_params = { | |
"lon": lon, | |
"lat": lat, | |
"property": [ | |
"bdod", "cec", "cfvo", "clay", "nitrogen", | |
"ocd", "ocs", "phh2o", "sand", "silt", | |
"soc", "wv0010", "wv0033", "wv1500" | |
], | |
"depth": "5-15cm", | |
"value": "mean" | |
} | |
try: | |
prop_response = requests.get(properties_url, params=properties_params, | |
headers=headers, timeout=timeout_val) | |
prop_response.raise_for_status() | |
prop_data = prop_response.json() | |
except Exception as e: | |
return jsonify({"error": "Failed to fetch soil properties: " + str(e)}), 500 | |
properties_list = [] | |
layers = prop_data.get("properties", {}).get("layers", []) | |
for layer in layers: | |
param_code = layer.get("name") | |
readable_name, description = PARAM_MAP.get(param_code, (param_code.upper(), "No description available")) | |
# Get the 'mean' value for the first depth entry | |
value = layer.get("depths", [{}])[0].get("values", {}).get("mean") | |
if value is not None: | |
if param_code in ["wv0010", "wv0033", "wv1500"]: | |
final_value = value / 10.0 | |
unit = layer.get("unit_measure", {}).get("target_units", "") | |
elif param_code == "phh2o": | |
final_value = value / 10.0 | |
unit = layer.get("unit_measure", {}).get("mapped_units", "").replace("*10", "").strip() or "pH" | |
else: | |
final_value = value | |
unit = layer.get("unit_measure", {}).get("mapped_units", "") | |
else: | |
final_value = "No Data" | |
unit = "" | |
properties_list.append({ | |
"parameter": readable_name, | |
"value": final_value, | |
"unit": unit, | |
"description": description | |
}) | |
soil_report = { | |
"classification": soil_classification, | |
"properties": properties_list | |
} | |
return jsonify(soil_report) | |
def analyze_soil(): | |
data = request.get_json() | |
soil_report = data.get("soil_report") | |
lat = data.get("lat") | |
lon = data.get("lon") | |
language = data.get("language", "English") | |
if not soil_report or not lat or not lon: | |
return jsonify({"error": "Incomplete data"}), 400 | |
# Extract soil classification and properties details | |
classification_data = soil_report.get("classification", {}) | |
soil_classification = classification_data.get("soil_type", "Unknown") | |
soil_properties = soil_report.get("properties", []) | |
prompt = f""" | |
Here is the soil report data: | |
- Classification: {classification_data} | |
- Soil Type: {soil_classification} | |
- Properties: {soil_properties} | |
- Location: Latitude {lat}, Longitude {lon} | |
Please generate a detailed soil report analysis with the following format: | |
1. A large, green, bold heading titled **Soil Report Analysis**. | |
2. Below that, display the soil type (left-aligned in black bold text) with proper spacing. | |
3. List 2-3 bullet points providing insights on the soil type and location. | |
4. Include a green-colored table listing soil parameters, their values, ranges (high, low, normal), and comments on these ranges. | |
5. Provide a suitable crops table in green with proper spacing, listing recommended crops based on the soil parameters, soil type, and location. | |
6. Finally, offer insights on fertilization type, irrigation type, and suitable agricultural practices. | |
Format the entire output in Markdown for proper HTML rendering. | |
diont give any useless cointnent except the reosnse liek i will search , i will reocmende,i cannotngive ex(just exmaples), proper tbales,allignment,jsutification,spaicng prpepr formatting and good look etc. | |
Please provide the analysis in {language}. | |
""" | |
try: | |
api_key = os.getenv("GEMINI_API") | |
# Initialize the new Google GenAI client using Gemini 1.5 Flash | |
client = genai.Client(api_key=api_key) | |
response = client.models.generate_content( | |
model="gemini-1.5-flash", | |
contents=prompt, | |
) | |
analysis = response.text | |
# Remove any triple quotes if present | |
if analysis.startswith("'''") and analysis.endswith("'''"): | |
analysis = analysis[3:-3] | |
except Exception as e: | |
analysis = "Gemini analysis not available: " + str(e) | |
analysis = markdown.markdown(analysis) | |
return jsonify({"analysis": analysis}) | |
if __name__ == '__main__': | |
app.run(debug=True, port=7860) | |