forked from atharrva01/cropdash
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
101 lines (83 loc) · 3.26 KB
/
server.py
File metadata and controls
101 lines (83 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import os
from flask import Flask, request, jsonify
import requests
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
OWM_KEY = os.environ.get('OPENWEATHER_API_KEY')
@app.get('/api/health')
def health():
return jsonify({"status":"ok"})
@app.get('/api/geocode')
def geocode():
q = request.args.get('location','')
if not q:
return jsonify({"error":"location is required"}), 400
if OWM_KEY:
u = f"https://api.openweathermap.org/geo/1.0/direct?q={requests.utils.quote(q)}&limit=1&appid={OWM_KEY}"
r = requests.get(u, timeout=15)
if r.status_code == 200:
j = r.json()
if j:
return jsonify({"lat": j[0]['lat'], "lon": j[0]['lon'], "name": j[0]['name']})
# Fallback to Open-Meteo geocoding (no key required)
mu = f"https://geocoding-api.open-meteo.com/v1/search?name={requests.utils.quote(q)}&count=1&language=en&format=json"
mr = requests.get(mu, timeout=15)
if mr.status_code != 200:
return jsonify({"error":"geocoding failed"}), mr.status_code
mj = mr.json()
res = (mj.get('results') or [])
if not res:
return jsonify({"error":"location not found"}), 404
first = res[0]
name = f"{first.get('name','')}" + (f", {first.get('country','')}" if first.get('country') else '')
return jsonify({"lat": first.get('latitude'), "lon": first.get('longitude'), "name": name})
@app.get('/api/onecall')
def onecall():
lat = request.args.get('lat')
lon = request.args.get('lon')
if not lat or not lon:
return jsonify({"error":"lat and lon required"}), 400
u = (
f"https://api.open-meteo.com/v1/forecast"
f"?latitude={lat}&longitude={lon}"
f"&daily=temperature_2m_mean,precipitation_sum"
f"&timezone=auto"
)
r = requests.get(u, timeout=20)
if r.status_code != 200:
return jsonify({"error":"weather fetch failed"}), r.status_code
return jsonify(r.json())
@app.get('/api/soil')
def soil():
lat = request.args.get('lat')
lon = request.args.get('lon')
if not lat or not lon:
return jsonify({"error":"lat and lon required"}), 400
u = (
f"https://rest.isric.org/soilgrids/v2.0/properties/query?"
f"lat={lat}&lon={lon}&property=phh2o&depth=0-5cm&value=mean"
)
r = requests.get(u, timeout=20)
if r.status_code != 200:
return jsonify({"error":"soil fetch failed"}), r.status_code
try:
j = r.json()
layers = j.get('properties', {}).get('layers', [])
layer = next((l for l in layers if l.get('name') == 'phh2o'), None)
if not layer:
return jsonify({"error": "soil pH not available"}), 404
# SoilGrids stores pH for multiple depths; pick first safe one
depths = layer.get('depths', [])
if not depths:
return jsonify({"error": "soil pH not available"}), 404
values = depths[0].get('values', {})
mean = values.get('mean')
if mean is None:
return jsonify({"error": "soil pH not available"}), 404
# SoilGrids phh2o is 10x actual pH (Deci-pH)
return jsonify({"ph": mean / 10})
except Exception:
return jsonify({"error":"soil parse error"}), 500
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5501)