akashub
feat(Initial project setup): Added code for initial setup
b20698b
raw
history blame
4.4 kB
import aiohttp
import asyncio
import os
import xarray as xr
import requests
from datetime import datetime
from typing import Dict, Any
# ============================================================================
# SOIL PROPERTIES SERVER (SoilGrids)
# ============================================================================
class SoilPropertiesServer:
"""SoilGrids API Server - Enhanced for reliability"""
async def get_data(self, lat: float, lon: float) -> Dict[str, Any]:
"""Get soil properties with retry logic and rate limit handling"""
try:
properties = ["clay", "sand", "silt", "phh2o", "soc"]
results = {}
timeout = aiohttp.ClientTimeout(total=15, connect=5, sock_read=10)
connector = aiohttp.TCPConnector(limit=1, limit_per_host=1)
async with aiohttp.ClientSession(timeout=timeout, connector=connector) as session:
for prop in properties:
# Retry logic (max 2 attempts)
for attempt in range(2):
try:
url = "https://rest.isric.org/soilgrids/v2.0/properties/query"
params = {
"lon": lon,
"lat": lat,
"property": prop,
"depth": "0-5cm",
"value": "mean"
}
async with session.get(url, params=params) as response:
if response.status == 200:
data = await response.json()
value = data['properties']['layers'][0]['depths'][0]['values']['mean']
if value is not None:
if prop == 'phh2o':
results[prop] = round(value / 10, 1)
elif prop == 'soc':
results[prop] = value
else:
results[prop] = round(value / 10, 1)
else:
results[prop] = None
break
elif response.status == 429:
if attempt == 0:
await asyncio.sleep(1)
continue
else:
results[prop] = None
break
else:
results[prop] = None
break
except asyncio.TimeoutError:
if attempt == 0:
await asyncio.sleep(0.5)
continue
else:
results[prop] = None
break
except Exception:
results[prop] = None
break
await asyncio.sleep(0.2) # Delay between properties
if any(v is not None for v in results.values()):
return {
"status": "success",
"data": {
"clay_percent": results.get("clay"),
"sand_percent": results.get("sand"),
"silt_percent": results.get("silt"),
"pH": results.get("phh2o"),
"organic_carbon_dg_per_kg": results.get("soc"),
"data_source": "SoilGrids API (ISRIC)",
"location": {"latitude": lat, "longitude": lon},
"depth": "0-5cm (topsoil)"
}
}
else:
return {
"status": "error",
"error": "No soil data available for this location"
}
except Exception as e:
return {"status": "error", "error": f"SoilGrids error: {str(e)}"}