Jacksonnavigator7 commited on
Commit
c560683
·
verified ·
1 Parent(s): 46c1415

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -136
app.py CHANGED
@@ -3,6 +3,7 @@ import gradio as gr
3
  import re
4
  import folium
5
  from fastai.vision.all import *
 
6
  from PIL import Image
7
  import time
8
  import json
@@ -12,6 +13,11 @@ from functools import lru_cache
12
  learn = load_learner('export.pkl')
13
  labels = learn.dls.vocab
14
 
 
 
 
 
 
15
  # Cache directory for API responses
16
  os.makedirs("cache", exist_ok=True)
17
 
@@ -130,43 +136,96 @@ def is_likely_bird_image(img):
130
  # If any error occurs during the check, assume it might be a bird
131
  return True
132
 
133
- def get_bird_habitat_map(bird_name):
134
- """Get habitat map locations for the bird - simplified without Groq"""
135
  clean_name = clean_bird_name(bird_name)
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  # Check cache for habitat locations
138
  habitat_cache_key = f"{clean_name}_habitat"
139
  cached_habitat = load_from_cache("habitat", habitat_cache_key)
140
  if cached_habitat is not None:
141
- # For already cached data, return with a default Tanzania presence value
142
- return cached_habitat, True
143
-
144
- # Default habitat locations for demonstration purposes
145
- default_locations = [
146
- {
147
- "name": "Serengeti National Park, Tanzania",
148
- "lat": -2.3333,
149
- "lon": 34.8333,
150
- "description": "Major savanna ecosystem with diverse bird habitats."
151
- },
152
- {
153
- "name": "Ngorongoro Conservation Area, Tanzania",
154
- "lat": -3.2,
155
- "lon": 35.5,
156
- "description": "Crater highlands with varying altitudes supporting different bird species."
157
- },
158
- {
159
- "name": "Tarangire National Park, Tanzania",
160
- "lat": -4.0,
161
- "lon": 36.0,
162
- "description": "Known for its baobab trees and seasonal swamps that attract various bird species."
163
- }
164
  ]
165
 
166
- # Cache the default result to avoid regenerating it
167
- save_to_cache("habitat", habitat_cache_key, default_locations)
168
 
169
- return default_locations, True # Assume bird is in Tanzania for simplicity
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  def create_habitat_map(habitat_locations):
172
  """Create a folium map with the habitat locations"""
@@ -235,7 +294,7 @@ def format_bird_info(raw_info, language="en"):
235
  return formatted
236
 
237
  def get_bird_info(bird_name, language="en"):
238
- """Get detailed information about a bird - simplified without Groq"""
239
  clean_name = clean_bird_name(bird_name)
240
 
241
  # Check cache first
@@ -244,70 +303,41 @@ def get_bird_info(bird_name, language="en"):
244
  if cached_info is not None:
245
  return cached_info
246
 
247
- # Generate basic info based on the bird name
248
- # This is a placeholder - in a real application, you would replace this with
249
- # a database lookup or another API call
 
250
 
251
- is_in_tanzania = True # Default assumption for demonstration
 
 
 
 
 
 
252
 
253
- if language == "sw":
254
- bird_info = f"""
255
- ## Maelezo ya {clean_name}
256
-
257
- ### Sifa za Kimwili na Mwonekano
258
- • Ndege huyu ana umbile la wastani na rangi nyeupe na nyeusi.
259
- • Ana mdomo mrefu na miguu myeupe.
260
-
261
- ### Makazi na Usambazaji
262
- • Hupatikana sana katika misitu na viunga vya maji nchini Tanzania.
263
- • Hupendelea maeneo yenye miti mingi na vyanzo vya maji.
264
-
265
- ### Lishe na Tabia
266
- • Hula wadudu na matunda madogo madogo.
267
- • Hutengeneza viota vyake juu ya miti.
268
-
269
- ### Mifumo ya Uhamiaji
270
- • Sio ndege mhamiaji, hupatikana nchini Tanzania mwaka mzima.
271
- • Husafiri katika makundi madogo madogo.
272
-
273
- ### Hali ya Uhifadhi
274
- • Haijaathiriwa sana na mabadiliko ya tabianchi.
275
- • Idadi yake ipo salama kwa sasa.
276
- """
277
- else:
278
- bird_info = f"""
279
- ## About the {clean_name}
280
-
281
- ### Physical Characteristics and Appearance
282
- • This bird has a medium build with distinctive white and black coloration.
283
- • It has a long beak and white legs.
284
-
285
- ### Habitat and Distribution
286
- • Commonly found in forests and near water bodies in Tanzania.
287
- • Prefers areas with abundant trees and water sources.
288
-
289
- ### Diet and Behavior
290
- • Feeds on insects and small fruits.
291
- • Builds nests high up in trees.
292
-
293
- ### Migration Patterns
294
- • Not a migratory bird, present in Tanzania year-round.
295
- • Travels in small flocks.
296
-
297
- ### Conservation Status
298
- • Not significantly affected by climate change yet.
299
- • Population remains stable.
300
- """
301
 
302
- # Add warning if not in Tanzania (for demonstration purposes, we'll assume random birds aren't in Tanzania)
303
- import random
304
- if not is_in_tanzania or random.random() > 0.7: # 30% chance to be marked as not in Tanzania
305
- warning = "NOT TYPICALLY FOUND IN TANZANIA\n\n" if language == "en" else "HAPATIKANI SANA TANZANIA\n\n"
306
- bird_info = warning + bird_info
307
 
308
- # Cache the result
309
- save_to_cache("bird_info", cache_key, bird_info)
310
- return bird_info
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
312
  def create_message_html(message, icon="🔍", language="en"):
313
  """Create a styled message container for notifications"""
@@ -315,7 +345,8 @@ def create_message_html(message, icon="🔍", language="en"):
315
  <style>
316
  .message-container {
317
  font-family: Arial, sans-serif;
318
- padding: 20px;
 
319
  background-color: #f8f9fa;
320
  border-radius: 8px;
321
  text-align: center;
@@ -484,54 +515,41 @@ def follow_up_question(question, bird_name, language="en"):
484
  if cached_answer is not None:
485
  return cached_answer
486
 
487
- # Generate a simple response based on the question
488
- # This is a placeholder - in a real application, you would replace this with
489
- # a database lookup or another API call
490
-
491
- clean_bird = clean_bird_name(bird_name)
492
-
493
- response_templates = {
494
- "en": {
495
- "habitat": f"The {clean_bird} typically inhabits forested areas and wetlands in Tanzania. They prefer areas with abundant tree cover and proximity to water sources for feeding and nesting.",
496
- "diet": f"The {clean_bird} primarily feeds on insects, small fruits, and seeds. They forage in trees and sometimes on the ground, using their specialized beak to extract food from various sources.",
497
- "migration": f"The {clean_bird} is generally a resident species in Tanzania, though some local movements may occur based on seasonal food availability. Climate change has not significantly altered their distribution patterns yet.",
498
- "conservation": f"The {clean_bird} currently has a stable population in Tanzania. Conservation efforts focus on habitat preservation, especially protecting the forests and wetlands where they breed.",
499
- "behavior": f"The {clean_bird} is known for its distinctive calls and social behavior. They often form small flocks and are more active during early morning and late afternoon hours.",
500
- "default": f"The {clean_bird} is an interesting bird species found in Tanzania. While specific information on your question is limited, ongoing research continues to expand our understanding of this species."
501
- },
502
- "sw": {
503
- "habitat": f"Ndege {clean_bird} huishi katika maeneo ya misitu na maeneo yenye maji nchini Tanzania. Hupendelea maeneo yenye miti mingi na karibu na vyanzo vya maji kwa ajili ya chakula na viota.",
504
- "diet": f"Ndege {clean_bird} hula wadudu, matunda madogo, na mbegu. Hutafuta chakula kwenye miti na wakati mwingine ardhini, akitumia mdomo wake maalum kutoa chakula kutoka vyanzo mbalimbali.",
505
- "migration": f"Ndege {clean_bird} kwa kawaida huishi Tanzania mwaka mzima, ingawa baadhi ya harakati za ndani hufanyika kulingana na upatikanaji wa chakula kwa msimu. Mabadiliko ya tabianchi hayajabadilisha sana mienendo yao ya usambazaji.",
506
- "conservation": f"Ndege {clean_bird} kwa sasa ana idadi imara nchini Tanzania. Juhudi za uhifadhi zinalenga kuhifadhi makazi, hasa kulinda misitu na nyanda za maji ambapo wanazaliana.",
507
- "behavior": f"Ndege {clean_bird} anajulikana kwa mwito wake wa kipekee na tabia ya kijamii. Mara nyingi huunda makundi madogo na wana shughuli zaidi wakati wa asubuhi na mchana.",
508
- "default": f"Ndege {clean_bird} ni spishi ya ndege ya kuvutia inayopatikana Tanzania. Ingawa taarifa mahususi kuhusu swali lako ni ndogo, utafiti unaoendelea unaendelea kupanua uelewa wetu wa spishi hii."
509
- }
510
- }
511
 
512
- # Simple keyword matching for response selection
513
- question_lower = question.lower()
514
- if language in response_templates:
515
- templates = response_templates[language]
516
- if any(word in question_lower for word in ["habitat", "live", "found", "where", "makazi", "anaishi", "anapatikana"]):
517
- response = templates["habitat"]
518
- elif any(word in question_lower for word in ["eat", "food", "diet", "feeding", "chakula", "kula", "lishe"]):
519
- response = templates["diet"]
520
- elif any(word in question_lower for word in ["migration", "move", "travel", "season", "uhamiaji", "safiri", "msimu"]):
521
- response = templates["migration"]
522
- elif any(word in question_lower for word in ["conserve", "protect", "endangered", "status", "uhifadhi", "linda", "hatarini"]):
523
- response = templates["conservation"]
524
- elif any(word in question_lower for word in ["behavior", "behaviour", "habit", "social", "tabia", "mazoea", "jamii"]):
525
- response = templates["behavior"]
526
- else:
527
- response = templates["default"]
528
- else:
529
- # Fallback to English
530
- response = response_templates["en"]["default"]
531
 
532
- # Cache the result
533
- save_to_cache("follow_up", cache_key, response)
534
- return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
 
536
  # Create the Gradio interface
537
  with gr.Blocks(theme=gr.themes.Soft()) as app:
 
3
  import re
4
  import folium
5
  from fastai.vision.all import *
6
+ from groq import Groq
7
  from PIL import Image
8
  import time
9
  import json
 
13
  learn = load_learner('export.pkl')
14
  labels = learn.dls.vocab
15
 
16
+ # Initialize Groq client
17
+ client = Groq(
18
+ api_key=os.environ.get("GROQ_API_KEY"),
19
+ )
20
+
21
  # Cache directory for API responses
22
  os.makedirs("cache", exist_ok=True)
23
 
 
136
  # If any error occurs during the check, assume it might be a bird
137
  return True
138
 
139
+ def get_bird_habitat_map(bird_name, check_tanzania=True):
140
+ """Get habitat map locations for the bird using Groq API with caching"""
141
  clean_name = clean_bird_name(bird_name)
142
 
143
+ # Check cache for Tanzania check
144
+ tanzania_cache_key = f"{clean_name}_tanzania"
145
+ cached_tanzania = load_from_cache("tanzania_check", tanzania_cache_key)
146
+ if cached_tanzania is not None:
147
+ is_in_tanzania = cached_tanzania
148
+ else:
149
+ # First check if the bird is endemic to Tanzania
150
+ if check_tanzania:
151
+ tanzania_check_prompt = f"""
152
+ Is the {clean_name} bird native to or commonly found in Tanzania?
153
+ Answer with ONLY "yes" or "no".
154
+ """
155
+
156
+ try:
157
+ tanzania_check = client.chat.completions.create(
158
+ messages=[{"role": "user", "content": tanzania_check_prompt}],
159
+ model="llama-3.3-70b-versatile",
160
+ )
161
+ is_in_tanzania = "yes" in tanzania_check.choices[0].message.content.lower()
162
+ # Cache result
163
+ save_to_cache("tanzania_check", tanzania_cache_key, is_in_tanzania)
164
+ except:
165
+ # Default to showing Tanzania if we can't determine
166
+ is_in_tanzania = True
167
+ else:
168
+ is_in_tanzania = True
169
+
170
  # Check cache for habitat locations
171
  habitat_cache_key = f"{clean_name}_habitat"
172
  cached_habitat = load_from_cache("habitat", habitat_cache_key)
173
  if cached_habitat is not None:
174
+ return cached_habitat, is_in_tanzania
175
+
176
+ # Now get the habitat locations
177
+ prompt = f"""
178
+ Provide a JSON array of the main habitat locations for the {clean_name} bird in the world.
179
+ Return ONLY a JSON array with 3-5 entries, each containing:
180
+ 1. "name": Location name
181
+ 2. "lat": Latitude (numeric value)
182
+ 3. "lon": Longitude (numeric value)
183
+ 4. "description": Brief description of why this is a key habitat (2-3 sentences)
184
+
185
+ Example format:
186
+ [
187
+ {{"name": "Example Location", "lat": 12.34, "lon": 56.78, "description": "Brief description"}},
188
+ ...
 
 
 
 
 
 
 
 
189
  ]
190
 
191
+ {'' if is_in_tanzania else 'DO NOT include any locations in Tanzania as this bird is not native to or commonly found there.'}
192
+ """
193
 
194
+ try:
195
+ chat_completion = client.chat.completions.create(
196
+ messages=[
197
+ {
198
+ "role": "user",
199
+ "content": prompt,
200
+ }
201
+ ],
202
+ model="llama-3.3-70b-versatile",
203
+ )
204
+ response = chat_completion.choices[0].message.content
205
+
206
+ # Extract JSON from response (in case there's additional text)
207
+ import json
208
+ import re
209
+
210
+ # Find JSON pattern in response
211
+ json_match = re.search(r'\[.*\]', response, re.DOTALL)
212
+ if json_match:
213
+ locations = json.loads(json_match.group())
214
+ else:
215
+ # Fallback if JSON extraction fails
216
+ locations = [
217
+ {"name": "Primary habitat region", "lat": 0, "lon": 0,
218
+ "description": "Could not retrieve specific habitat information for this bird."}
219
+ ]
220
+
221
+ # Cache the result
222
+ save_to_cache("habitat", habitat_cache_key, locations)
223
+
224
+ return locations, is_in_tanzania
225
+
226
+ except Exception as e:
227
+ return [{"name": "Error retrieving data", "lat": 0, "lon": 0,
228
+ "description": "Please try again or check your connection."}], False
229
 
230
  def create_habitat_map(habitat_locations):
231
  """Create a folium map with the habitat locations"""
 
294
  return formatted
295
 
296
  def get_bird_info(bird_name, language="en"):
297
+ """Get detailed information about a bird using Groq API with caching"""
298
  clean_name = clean_bird_name(bird_name)
299
 
300
  # Check cache first
 
303
  if cached_info is not None:
304
  return cached_info
305
 
306
+ # Adjust language for the prompt
307
+ lang_instruction = ""
308
+ if language == "sw":
309
+ lang_instruction = " Provide your response in Swahili language."
310
 
311
+ prompt = f"""
312
+ Provide detailed information about the {clean_name} bird, including:
313
+ 1. Physical characteristics and appearance
314
+ 2. Habitat and distribution
315
+ 3. Diet and behavior
316
+ 4. Migration patterns (emphasize if this pattern has changed in recent years due to climate change)
317
+ 5. Conservation status
318
 
319
+ If this bird is not commonly found in Tanzania, explicitly flag that this bird is "NOT TYPICALLY FOUND IN TANZANIA" at the beginning of your response and explain why its presence might be unusual.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
+ Format your response in markdown for better readability.{lang_instruction}
322
+ """
 
 
 
323
 
324
+ try:
325
+ chat_completion = client.chat.completions.create(
326
+ messages=[
327
+ {
328
+ "role": "user",
329
+ "content": prompt,
330
+ }
331
+ ],
332
+ model="llama-3.3-70b-versatile",
333
+ )
334
+ response = chat_completion.choices[0].message.content
335
+ # Cache the result
336
+ save_to_cache("bird_info", cache_key, response)
337
+ return response
338
+ except Exception as e:
339
+ error_msg = "Hitilafu katika kupata taarifa" if language == "sw" else "Error fetching information"
340
+ return f"{error_msg}: {str(e)}"
341
 
342
  def create_message_html(message, icon="🔍", language="en"):
343
  """Create a styled message container for notifications"""
 
345
  <style>
346
  .message-container {
347
  font-family: Arial, sans-serif;
348
+ padding:
349
+ 20px;
350
  background-color: #f8f9fa;
351
  border-radius: 8px;
352
  text-align: center;
 
515
  if cached_answer is not None:
516
  return cached_answer
517
 
518
+ # Adjust language for the prompt
519
+ lang_instruction = ""
520
+ if language == "sw":
521
+ lang_instruction = " Provide your response in Swahili language."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
 
523
+ prompt = f"""
524
+ The researcher is asking about the {bird_name} bird: "{question}"
525
+
526
+ Provide a detailed, scientific answer focusing on accurate ornithological information.
527
+ If the question relates to Tanzania or climate change impacts, emphasize those aspects in your response.
528
+
529
+ IMPORTANT: Do not repeat basic introductory information about the bird that would have already been provided in a general description.
530
+ Do not start your answer with phrases like "Introduction to the {bird_name}" or similar repetitive headers.
531
+ Directly answer the specific question asked.
 
 
 
 
 
 
 
 
 
 
532
 
533
+ Format your response in markdown for better readability.{lang_instruction}
534
+ """
535
+
536
+ try:
537
+ chat_completion = client.chat.completions.create(
538
+ messages=[
539
+ {
540
+ "role": "user",
541
+ "content": prompt,
542
+ }
543
+ ],
544
+ model="llama-3.3-70b-versatile",
545
+ )
546
+ response = chat_completion.choices[0].message.content
547
+ # Cache the result
548
+ save_to_cache("follow_up", cache_key, response)
549
+ return response
550
+ except Exception as e:
551
+ error_msg = "Hitilafu katika kupata taarifa" if language == "sw" else "Error fetching information"
552
+ return f"{error_msg}: {str(e)}"
553
 
554
  # Create the Gradio interface
555
  with gr.Blocks(theme=gr.themes.Soft()) as app: