Wall06 commited on
Commit
c5db957
·
verified ·
1 Parent(s): d3777ae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +231 -0
app.py CHANGED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import numpy as np
4
+ import pandas as pd
5
+ import matplotlib.pyplot as plt
6
+ import plotly.graph_objects as go
7
+ import requests
8
+ import cv2
9
+ from PIL import Image
10
+ import qrcode
11
+ from fpdf import FPDF
12
+ from io import BytesIO
13
+ from sentinelhub import SHConfig, MimeType, CRS, BBox, SentinelHubRequest, DataCollection
14
+ from groq import Groq
15
+
16
+ # -------------------- ENVIRONMENT VARIABLES --------------------
17
+ HF_API_KEY = os.getenv("HF_API_KEY")
18
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
19
+ DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
20
+ SENTINEL_CLIENT_ID = os.getenv("SENTINEL_CLIENT_ID")
21
+ SENTINEL_CLIENT_SECRET = os.getenv("SENTINEL_CLIENT_SECRET")
22
+
23
+ # -------------------- SENTINEL HUB CONFIG --------------------
24
+ config = SHConfig()
25
+ config.client_id = SENTINEL_CLIENT_ID
26
+ config.client_secret = SENTINEL_CLIENT_SECRET
27
+
28
+ # -------------------- AI SUMMARY FUNCTIONS --------------------
29
+ def hf_summary(text):
30
+ try:
31
+ url = "https://api-inference.huggingface.co/models/google/flan-t5-large"
32
+ headers = {"Authorization": f"Bearer {HF_API_KEY}"}
33
+ r = requests.post(url, headers=headers, json={"inputs": text}, timeout=20)
34
+ return r.json()[0]["generated_text"]
35
+ except:
36
+ return None
37
+
38
+ def groq_summary(text):
39
+ try:
40
+ client = Groq(api_key=GROQ_API_KEY)
41
+ completion = client.chat.completions.create(
42
+ model="mixtral-8x7b-32768",
43
+ messages=[{"role": "user", "content": text}]
44
+ )
45
+ return completion.choices[0].message["content"]
46
+ except:
47
+ return None
48
+
49
+ def deepseek_summary(text):
50
+ try:
51
+ url = "https://api.deepseek.com/v1/chat/completions"
52
+ headers = {
53
+ "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
54
+ "Content-Type": "application/json"
55
+ }
56
+ payload = {
57
+ "model": "deepseek-chat",
58
+ "messages": [{"role": "user", "content": text}]
59
+ }
60
+ r = requests.post(url, headers=headers, json=payload, timeout=20)
61
+ return r.json()["choices"][0]["message"]["content"]
62
+ except:
63
+ return None
64
+
65
+ def smart_summary(text):
66
+ if GROQ_API_KEY:
67
+ out = groq_summary(text)
68
+ if out: return out
69
+ if DEEPSEEK_API_KEY:
70
+ out = deepseek_summary(text)
71
+ if out: return out
72
+ if HF_API_KEY:
73
+ out = hf_summary(text)
74
+ if out: return out
75
+ return "⚠ No AI model available. Check API keys."
76
+
77
+ # -------------------- WATER QUALITY CALCULATIONS --------------------
78
+ def calculate_wqi(pH, do, nutrients):
79
+ wqi = (7 - abs(7 - pH)) * 0.2 + (do/14) * 0.5 + (10 - nutrients) * 0.3
80
+ wqi_score = max(0, min(100, int(wqi*10)))
81
+ return wqi_score
82
+
83
+ def calculate_hsi(flow_rate, temp, sediment):
84
+ hsi = 100 - abs(flow_rate-50)*0.5 - abs(temp-20)*2 - sediment*1.5
85
+ return max(0, min(100, int(hsi)))
86
+
87
+ def calculate_erosion(sediment, construction):
88
+ score = sediment*1.5 + construction*2
89
+ return max(0, min(100, int(score)))
90
+
91
+ def potability_status(wqi):
92
+ if wqi > 80: return "Safe"
93
+ elif wqi > 50: return "Boil Required"
94
+ else: return "Toxic"
95
+
96
+ def river_stability(wqi, hsi, erosion):
97
+ return int((wqi*0.4 + hsi*0.4 + (100-erosion)*0.2))
98
+
99
+ # -------------------- SATELLITE IMAGE ANALYSIS --------------------
100
+ def analyze_satellite_image(img):
101
+ img_array = np.array(img.convert("L"))
102
+ turbidity_score = int(np.mean(img_array)/2.55) # scale 0-100
103
+ return turbidity_score
104
+
105
+ # -------------------- PLOTLY CHARTS --------------------
106
+ def create_plots(wqi, hsi, erosion, turbidity):
107
+ fig = go.Figure()
108
+ fig.add_trace(go.Bar(name="WQI", x=["WQI"], y=[wqi], marker_color='blue'))
109
+ fig.add_trace(go.Bar(name="HSI", x=["HSI"], y=[hsi], marker_color='green'))
110
+ fig.add_trace(go.Bar(name="Erosion", x=["Erosion"], y=[erosion], marker_color='red'))
111
+ fig.add_trace(go.Bar(name="Turbidity", x=["Turbidity"], y=[turbidity], marker_color='orange'))
112
+ fig.update_layout(title="River Health Metrics", barmode='group', yaxis=dict(range=[0,100]))
113
+ return fig
114
+
115
+ # -------------------- PDF GENERATION --------------------
116
+ def generate_pdf(wqi, hsi, erosion, turbidity, summary_text):
117
+ pdf = FPDF()
118
+ pdf.add_page()
119
+ pdf.set_font("Arial", "B", 16)
120
+ pdf.cell(0, 10, "FlumenIntel River Health Report", ln=True, align='C')
121
+ pdf.set_font("Arial", "", 12)
122
+ pdf.ln(10)
123
+
124
+ # Metrics
125
+ pdf.cell(0,10,f"WQI Score: {wqi}", ln=True)
126
+ pdf.cell(0,10,f"HSI Score: {hsi}", ln=True)
127
+ pdf.cell(0,10,f"Erosion Potential: {erosion}", ln=True)
128
+ pdf.cell(0,10,f"Turbidity: {turbidity}", ln=True)
129
+ pdf.ln(10)
130
+
131
+ # AI Summary + Biodiversity / Mitigation
132
+ pdf.multi_cell(0, 8, summary_text)
133
+
134
+ # QR code
135
+ qr = qrcode.QRCode(box_size=4)
136
+ qr.add_data("FlumenIntel")
137
+ qr.make(fit=True)
138
+ img = qr.make_image(fill_color="black", back_color="white")
139
+ qr_buffer = BytesIO()
140
+ img.save(qr_buffer, format="PNG")
141
+ qr_buffer.seek(0)
142
+ pdf.image(qr_buffer, x=80, y=pdf.get_y(), w=50)
143
+
144
+ output = BytesIO()
145
+ pdf.output(output)
146
+ output.seek(0)
147
+ return output
148
+
149
+ # -------------------- MAIN FUNCTION --------------------
150
+ def predict_river(flow_rate, water_temp, sediment, construction, pH, do, nutrients, sat_img):
151
+ try:
152
+ # Scores
153
+ wqi = calculate_wqi(pH, do, nutrients)
154
+ hsi = calculate_hsi(flow_rate, water_temp, sediment)
155
+ erosion = calculate_erosion(sediment, construction)
156
+ turbidity = analyze_satellite_image(sat_img)
157
+ stability = river_stability(wqi, hsi, erosion)
158
+ potability = potability_status(wqi)
159
+
160
+ # AI Summary Input for full report
161
+ summary_input = f"""
162
+ Hydrological Data:
163
+ - Flow rate: {flow_rate} m³/s
164
+ - Water temperature: {water_temp} °C
165
+ - Sediment: {sediment}
166
+ - Construction: {construction}
167
+
168
+ Chemical Data:
169
+ - pH: {pH}
170
+ - Dissolved Oxygen: {do} mg/L
171
+ - Nutrient Load: {nutrients}
172
+
173
+ Satellite Analysis:
174
+ - Turbidity Score: {turbidity}
175
+
176
+ Derived Scores:
177
+ - WQI: {wqi}
178
+ - HSI: {hsi}
179
+ - Erosion: {erosion}
180
+ - Potability: {potability}
181
+ - Stability: {stability}
182
+
183
+ Generate a **comprehensive environmental report** that includes:
184
+ 1. River health summary
185
+ 2. Potential impact on biodiversity and fish
186
+ 3. Recommended mitigation measures with explanation
187
+ 4. Suggested monitoring frequency
188
+ """
189
+ summary = smart_summary(summary_input)
190
+
191
+ # Plot
192
+ fig = create_plots(wqi, hsi, erosion, turbidity)
193
+
194
+ # PDF
195
+ pdf_file = generate_pdf(wqi, hsi, erosion, turbidity, summary)
196
+
197
+ return f"River Stability: {stability}/100\nPotability: {potability}", fig, pdf_file, summary
198
+ except Exception as e:
199
+ return f"Error: {str(e)}", None, None, None
200
+
201
+ # -------------------- GRADIO UI --------------------
202
+ with gr.Blocks(title="FlumenIntel - River Health Predictor") as demo:
203
+ gr.Markdown("<h1 style='text-align:center;color:#1E90FF'>FlumenIntel 🌊</h1>", elem_id="title")
204
+ with gr.Row():
205
+ with gr.Column():
206
+ flow_rate = gr.Number(label="Flow Rate (m³/s)", value=50)
207
+ water_temp = gr.Number(label="Water Temperature (°C)", value=20)
208
+ sediment = gr.Number(label="Sediment Level", value=5)
209
+ construction = gr.Number(label="Construction Activity Level", value=2)
210
+ pH = gr.Number(label="pH Level", value=7)
211
+ do = gr.Number(label="Dissolved Oxygen (mg/L)", value=8)
212
+ nutrients = gr.Number(label="Nutrient Load (N+P)", value=3)
213
+ sat_img = gr.Image(label="Satellite Image (Upload or URL)", type="pil")
214
+ predict_btn = gr.Button("Predict River Health")
215
+ with gr.Column():
216
+ result_text = gr.Textbox(label="Predicted Output", interactive=False)
217
+ plot_output = gr.Plot(label="River Health Metrics")
218
+ pdf_output = gr.File(label="Download PDF Report")
219
+ ai_summary = gr.Textbox(label="AI Environmental Summary", interactive=False)
220
+
221
+ predict_btn.click(
222
+ predict_river,
223
+ inputs=[flow_rate, water_temp, sediment, construction, pH, do, nutrients, sat_img],
224
+ outputs=[result_text, plot_output, pdf_output, ai_summary]
225
+ )
226
+
227
+ # -------------------- CUSTOM CSS --------------------
228
+ custom_css = """
229
+ #title {background: linear-gradient(90deg, #1E90FF, #00CED1); padding: 20px; border-radius: 15px; color:white;}
230
+ """
231
+ demo.launch(share=True, css=custom_css)