Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
changes to app
Browse files
app.py
CHANGED
@@ -40,8 +40,9 @@ def format_whisp_statistics(df):
|
|
40 |
area = get_value(df, "Area")
|
41 |
try:
|
42 |
area = round(float(area), 2)
|
|
|
43 |
except:
|
44 |
-
|
45 |
|
46 |
risk_level = get_value(df, "risk_level")
|
47 |
risk_pcrop = get_value(df, "risk_pcrop")
|
@@ -49,25 +50,44 @@ def format_whisp_statistics(df):
|
|
49 |
risk_timber = get_value(df, "risk_timber")
|
50 |
def_after_2020 = get_value(df, "TMF_def_after_2020")
|
51 |
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
|
55 |
-
- Country: {country}
|
56 |
-
- Administrative Region: {admin_level}
|
57 |
-
- Total Area: {area} hectares
|
58 |
|
59 |
-
|
60 |
-
-
|
61 |
-
-
|
62 |
-
-
|
63 |
-
- Timber Risk: {risk_timber}
|
64 |
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
"""
|
68 |
return output
|
69 |
except Exception as e:
|
70 |
-
return f"Error formatting
|
71 |
|
72 |
def handle_geojson_upload(file):
|
73 |
"""Handle GeoJSON file upload and call WHISP API"""
|
@@ -110,10 +130,9 @@ def handle_geojson_upload(file):
|
|
110 |
|
111 |
def retrieve_paragraphs(query):
|
112 |
"""Connect to retriever and retrieve paragraphs"""
|
113 |
-
|
114 |
try:
|
115 |
# Call the API with the uploaded file
|
116 |
-
client = Client("https://giz-
|
117 |
result = client.predict(
|
118 |
query=query,
|
119 |
reports_filter="",
|
@@ -122,7 +141,7 @@ def retrieve_paragraphs(query):
|
|
122 |
year_filter="",
|
123 |
api_name="/retrieve"
|
124 |
)
|
125 |
-
|
126 |
return (
|
127 |
result,
|
128 |
gr.update(visible=True), # Keep status visible
|
@@ -130,18 +149,12 @@ def retrieve_paragraphs(query):
|
|
130 |
)
|
131 |
|
132 |
except Exception as e:
|
133 |
-
error_msg=
|
134 |
return (
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
else:
|
140 |
-
return (
|
141 |
-
"",
|
142 |
-
gr.update(visible=False), # upload_status
|
143 |
-
gr.update(visible=False) # results_table
|
144 |
-
)
|
145 |
|
146 |
def start_chat(query, history):
|
147 |
"""Start a new chat interaction"""
|
@@ -152,61 +165,6 @@ def finish_chat():
|
|
152 |
"""Finish chat and reset input"""
|
153 |
return gr.update(interactive=True, value="")
|
154 |
|
155 |
-
# async def chat_response(query, history, method, country, uploaded_file):
|
156 |
-
|
157 |
-
# """Generate chat response based on method and inputs"""
|
158 |
-
|
159 |
-
# # Validate inputs based on method
|
160 |
-
# if method == "Upload GeoJSON":
|
161 |
-
# if uploaded_file is None:
|
162 |
-
# warning_message = "⚠️ **No GeoJSON file uploaded.** Please upload a GeoJSON file first."
|
163 |
-
# history[-1] = (query, warning_message)
|
164 |
-
# yield history, ""
|
165 |
-
# return
|
166 |
-
# else: # "Talk to Reports"
|
167 |
-
# if not country:
|
168 |
-
# warning_message = "⚠️ **No country selected.** Please select a country to analyze reports."
|
169 |
-
# history[-1] = (query, warning_message)
|
170 |
-
# yield history, ""
|
171 |
-
# return
|
172 |
-
|
173 |
-
# # Get the formatted statistics if a file was just uploaded
|
174 |
-
# if method == "Upload GeoJSON" and uploaded_file:
|
175 |
-
# try:
|
176 |
-
# stats_result = handle_geojson_upload(uploaded_file)
|
177 |
-
# formatted_stats = stats_result[0] # Get the formatted statistics
|
178 |
-
# response = formatted_stats
|
179 |
-
# except Exception as e:
|
180 |
-
# response = f"Error processing file: {str(e)}"
|
181 |
-
# elif method == "Upload GeoJSON":
|
182 |
-
# response = f"Based on your uploaded GeoJSON file, I can help you analyze the deforestation patterns and EUDR compliance aspects in your area of interest. Your question: '{query}' is being processed against the geographic data you provided."
|
183 |
-
|
184 |
-
# # Talk to report
|
185 |
-
# else:
|
186 |
-
# try:
|
187 |
-
# # response = f"Based on EUDR reports for {country}, I can help you understand deforestation patterns and compliance requirements. Your question: '{query}' is being analyzed against our {country} database."
|
188 |
-
|
189 |
-
# # Retrieve info
|
190 |
-
# print("retrieve info")
|
191 |
-
# retrieved_info = retrieve_paragraphs(query)[0]
|
192 |
-
# response = retrieved_info
|
193 |
-
|
194 |
-
# except Exception as e:
|
195 |
-
# response = f"Error retrieving information: {str(e)}"
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
# # else:
|
200 |
-
# # response = f"Based on EUDR reports for {country}, I can help you understand deforestation patterns and compliance requirements. Your question: '{query}' is being analyzed against our {country} database."
|
201 |
-
|
202 |
-
# # Simulate streaming response
|
203 |
-
# words = response.split()
|
204 |
-
# for word in words:
|
205 |
-
# history[-1] = (query, " ".join(words[:words.index(word)+1]))
|
206 |
-
# yield history, "**Sources:** Sample source documents would appear here..."
|
207 |
-
# await asyncio.sleep(0.05)
|
208 |
-
|
209 |
-
|
210 |
async def chat_response(query, history, method, country, uploaded_file):
|
211 |
"""Generate chat response based on method and inputs"""
|
212 |
|
@@ -227,7 +185,9 @@ async def chat_response(query, history, method, country, uploaded_file):
|
|
227 |
# Handle GeoJSON upload → put formatted stats into chat
|
228 |
if method == "Upload GeoJSON" and uploaded_file:
|
229 |
try:
|
230 |
-
|
|
|
|
|
231 |
response = formatted_stats
|
232 |
except Exception as e:
|
233 |
response = f"Error processing file: {str(e)}"
|
@@ -248,6 +208,33 @@ async def chat_response(query, history, method, country, uploaded_file):
|
|
248 |
yield history, "**Sources:** Sample source documents would appear here..."
|
249 |
await asyncio.sleep(0.05)
|
250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
def toggle_search_method(method):
|
252 |
"""Toggle between GeoJSON upload and country selection"""
|
253 |
if method == "Upload GeoJSON":
|
@@ -516,17 +503,16 @@ with gr.Blocks(title="EUDR Q&A", theme=theme, css=custom_css) as demo:
|
|
516 |
outputs=[geojson_section, reports_section, dropdown_country]
|
517 |
)
|
518 |
|
519 |
-
# File upload - automatically
|
520 |
-
# uploaded_file.change(
|
521 |
-
# fn=handle_geojson_upload,
|
522 |
-
# inputs=[uploaded_file],
|
523 |
-
# outputs=[upload_status, upload_status, results_table]
|
524 |
-
# )
|
525 |
-
|
526 |
uploaded_file.change(
|
527 |
-
|
528 |
-
|
529 |
-
|
|
|
|
|
|
|
|
|
|
|
530 |
)
|
531 |
|
532 |
# Chat functionality
|
@@ -585,4 +571,4 @@ with gr.Blocks(title="EUDR Q&A", theme=theme, css=custom_css) as demo:
|
|
585 |
|
586 |
# Launch the app
|
587 |
if __name__ == "__main__":
|
588 |
-
demo.launch()
|
|
|
40 |
area = get_value(df, "Area")
|
41 |
try:
|
42 |
area = round(float(area), 2)
|
43 |
+
area_text = f"{area:,} hectares"
|
44 |
except:
|
45 |
+
area_text = str(area)
|
46 |
|
47 |
risk_level = get_value(df, "risk_level")
|
48 |
risk_pcrop = get_value(df, "risk_pcrop")
|
|
|
50 |
risk_timber = get_value(df, "risk_timber")
|
51 |
def_after_2020 = get_value(df, "TMF_def_after_2020")
|
52 |
|
53 |
+
# Helper function to format risk levels
|
54 |
+
def format_risk(risk_val):
|
55 |
+
if isinstance(risk_val, str):
|
56 |
+
risk_val = risk_val.lower()
|
57 |
+
if risk_val in ['low', 'medium', 'high', 'very high']:
|
58 |
+
return risk_val.title()
|
59 |
+
return str(risk_val)
|
60 |
|
61 |
+
output = f"""🌍 **Analysis Results for Your Geographic Area**
|
|
|
|
|
|
|
62 |
|
63 |
+
## 📍 **Plot Information**
|
64 |
+
- **Country**: {country}
|
65 |
+
- **Administrative Region**: {admin_level}
|
66 |
+
- **Total Area**: {area_text}
|
|
|
67 |
|
68 |
+
## ⚠️ **Risk Assessment**
|
69 |
+
*Risk levels indicate the likelihood of deforestation based on historical patterns and environmental factors*
|
70 |
+
|
71 |
+
- **Overall Deforestation Risk**: {format_risk(risk_level)}
|
72 |
+
- **Permanent Crop Risk**: {format_risk(risk_pcrop)}
|
73 |
+
*(Risk from permanent crops like coffee, cocoa, palm oil)*
|
74 |
+
- **Annual Crop Risk**: {format_risk(risk_acrop)}
|
75 |
+
*(Risk from seasonal crops like soy, corn, rice)*
|
76 |
+
- **Timber Risk**: {format_risk(risk_timber)}
|
77 |
+
*(Risk from logging and timber extraction activities)*
|
78 |
+
|
79 |
+
## 🌳 **Deforestation Analysis**
|
80 |
+
*Analysis based on Tropical Moist Forest (TMF) satellite data*
|
81 |
+
|
82 |
+
- **Recent Deforestation (Post-2020)**: {def_after_2020}
|
83 |
+
*(Forest loss detected after 2020, relevant for EUDR compliance)*
|
84 |
+
|
85 |
+
---
|
86 |
+
💡 **Understanding Your Results**: Higher risk levels indicate areas where deforestation is more likely to occur. For EUDR compliance, pay special attention to areas with recent deforestation after 2020, as this may affect commodity sourcing eligibility.
|
87 |
"""
|
88 |
return output
|
89 |
except Exception as e:
|
90 |
+
return f"❌ Error formatting analysis results: {str(e)}\n\nPlease check that your GeoJSON file is valid and try again."
|
91 |
|
92 |
def handle_geojson_upload(file):
|
93 |
"""Handle GeoJSON file upload and call WHISP API"""
|
|
|
130 |
|
131 |
def retrieve_paragraphs(query):
|
132 |
"""Connect to retriever and retrieve paragraphs"""
|
|
|
133 |
try:
|
134 |
# Call the API with the uploaded file
|
135 |
+
client = Client("https://giz-chatfed-retriever.hf.space/")
|
136 |
result = client.predict(
|
137 |
query=query,
|
138 |
reports_filter="",
|
|
|
141 |
year_filter="",
|
142 |
api_name="/retrieve"
|
143 |
)
|
144 |
+
print(result)
|
145 |
return (
|
146 |
result,
|
147 |
gr.update(visible=True), # Keep status visible
|
|
|
149 |
)
|
150 |
|
151 |
except Exception as e:
|
152 |
+
error_msg = f"Error retrieving paragraphs: {str(e)}"
|
153 |
return (
|
154 |
+
error_msg,
|
155 |
+
gr.update(visible=True), # upload_status
|
156 |
+
gr.update(visible=False) # results_table
|
157 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
|
159 |
def start_chat(query, history):
|
160 |
"""Start a new chat interaction"""
|
|
|
165 |
"""Finish chat and reset input"""
|
166 |
return gr.update(interactive=True, value="")
|
167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
async def chat_response(query, history, method, country, uploaded_file):
|
169 |
"""Generate chat response based on method and inputs"""
|
170 |
|
|
|
185 |
# Handle GeoJSON upload → put formatted stats into chat
|
186 |
if method == "Upload GeoJSON" and uploaded_file:
|
187 |
try:
|
188 |
+
# handle_geojson_upload returns a tuple (formatted_stats, gr.update(), gr.update())
|
189 |
+
stats_result = handle_geojson_upload(uploaded_file)
|
190 |
+
formatted_stats = stats_result[0] # Extract just the formatted statistics
|
191 |
response = formatted_stats
|
192 |
except Exception as e:
|
193 |
response = f"Error processing file: {str(e)}"
|
|
|
208 |
yield history, "**Sources:** Sample source documents would appear here..."
|
209 |
await asyncio.sleep(0.05)
|
210 |
|
211 |
+
def auto_analyze_file(file, history):
|
212 |
+
"""Automatically analyze uploaded GeoJSON file and add results to chat"""
|
213 |
+
if file is not None:
|
214 |
+
# Add a system message indicating file upload
|
215 |
+
analysis_query = "📄 GeoJSON file uploaded - analyzing..."
|
216 |
+
history = history + [(analysis_query, None)]
|
217 |
+
return history, analysis_query
|
218 |
+
return history, ""
|
219 |
+
|
220 |
+
def auto_display_results(query, history, uploaded_file):
|
221 |
+
"""Display analysis results automatically after file upload"""
|
222 |
+
if uploaded_file is not None and query.startswith("📄 GeoJSON file uploaded"):
|
223 |
+
try:
|
224 |
+
# Get the analysis results
|
225 |
+
stats_result = handle_geojson_upload(uploaded_file)
|
226 |
+
formatted_stats = stats_result[0] # Extract formatted statistics
|
227 |
+
|
228 |
+
# Update the chat with results
|
229 |
+
history[-1] = (query, formatted_stats)
|
230 |
+
return history, "**Sources:** WhispAPI Analysis Results"
|
231 |
+
except Exception as e:
|
232 |
+
error_msg = f"❌ Error processing GeoJSON file: {str(e)}"
|
233 |
+
history[-1] = (query, error_msg)
|
234 |
+
return history, ""
|
235 |
+
|
236 |
+
return history, ""
|
237 |
+
|
238 |
def toggle_search_method(method):
|
239 |
"""Toggle between GeoJSON upload and country selection"""
|
240 |
if method == "Upload GeoJSON":
|
|
|
503 |
outputs=[geojson_section, reports_section, dropdown_country]
|
504 |
)
|
505 |
|
506 |
+
# File upload - automatically analyze and display in chat
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
uploaded_file.change(
|
508 |
+
fn=auto_analyze_file,
|
509 |
+
inputs=[uploaded_file, chatbot],
|
510 |
+
outputs=[chatbot, examples_hidden],
|
511 |
+
queue=False
|
512 |
+
).then(
|
513 |
+
fn=auto_display_results,
|
514 |
+
inputs=[examples_hidden, chatbot, uploaded_file],
|
515 |
+
outputs=[chatbot, sources_textbox]
|
516 |
)
|
517 |
|
518 |
# Chat functionality
|
|
|
571 |
|
572 |
# Launch the app
|
573 |
if __name__ == "__main__":
|
574 |
+
demo.launch()
|