lyimo commited on
Commit
25a67ca
·
verified ·
1 Parent(s): 0e3e5e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -19
app.py CHANGED
@@ -27,10 +27,30 @@ def clean_bird_name(name):
27
  cleaned = ' '.join(cleaned.split())
28
  return cleaned
29
 
30
- def get_bird_habitat_map(bird_name):
31
  """Get habitat map locations for the bird using Groq API"""
32
  clean_name = clean_bird_name(bird_name)
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  prompt = f"""
35
  Provide a JSON array of the main habitat locations for the {clean_name} bird in the world.
36
  Return ONLY a JSON array with 3-5 entries, each containing:
@@ -45,7 +65,7 @@ def get_bird_habitat_map(bird_name):
45
  ...
46
  ]
47
 
48
- If this bird is not commonly found in Tanzania, include at least one location in Tanzania with a note about its unusual presence there.
49
  """
50
 
51
  try:
@@ -71,20 +91,32 @@ def get_bird_habitat_map(bird_name):
71
  else:
72
  # Fallback if JSON extraction fails
73
  locations = [
74
- {"name": "Habitat information unavailable", "lat": 0, "lon": 0,
75
- "description": "Could not retrieve habitat information for this bird."}
76
  ]
77
 
78
- return locations
79
 
80
  except Exception as e:
81
- return [{"name": f"Error retrieving habitat data: {str(e)}", "lat": 0, "lon": 0,
82
- "description": "Please try again or check your connection."}]
83
 
84
  def create_habitat_map(habitat_locations):
85
  """Create a folium map with the habitat locations"""
86
- # Create a world-centered map
87
- m = folium.Map(location=[20, 0], zoom_start=2)
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  # Add markers for each habitat location
90
  for location in habitat_locations:
@@ -108,6 +140,29 @@ def create_habitat_map(habitat_locations):
108
  map_html = m._repr_html_()
109
  return map_html
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  def get_bird_info(bird_name):
112
  """Get detailed information about a bird using Groq API"""
113
  clean_name = clean_bird_name(bird_name)
@@ -162,22 +217,68 @@ def predict_and_get_info(img):
162
  clean_top_bird = clean_bird_name(top_bird)
163
 
164
  # Get habitat locations and create map
165
- habitat_locations = get_bird_habitat_map(top_bird)
166
  habitat_map_html = create_habitat_map(habitat_locations)
167
 
168
  # Get detailed information about the top predicted bird
169
  bird_info = get_bird_info(top_bird)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
- # Create combined info with map at the top
172
  combined_info = f"""
173
- ## Natural Habitat Map for {clean_top_bird}
174
- <div style="height: 400px; width: 100%; border: 1px solid #ddd; border-radius: 8px; overflow: hidden; margin-bottom: 20px;">
175
- {habitat_map_html}
176
- </div>
177
-
178
- ## Detailed Information
179
- {bird_info}
180
- """
 
 
 
 
 
181
 
182
  return prediction_results, combined_info, clean_top_bird
183
 
 
27
  cleaned = ' '.join(cleaned.split())
28
  return cleaned
29
 
30
+ def get_bird_habitat_map(bird_name, check_tanzania=True):
31
  """Get habitat map locations for the bird using Groq API"""
32
  clean_name = clean_bird_name(bird_name)
33
 
34
+ # First check if the bird is endemic to Tanzania
35
+ if check_tanzania:
36
+ tanzania_check_prompt = f"""
37
+ Is the {clean_name} bird native to or commonly found in Tanzania?
38
+ Answer with ONLY "yes" or "no".
39
+ """
40
+
41
+ try:
42
+ tanzania_check = client.chat.completions.create(
43
+ messages=[{"role": "user", "content": tanzania_check_prompt}],
44
+ model="llama-3.3-70b-versatile",
45
+ )
46
+ is_in_tanzania = "yes" in tanzania_check.choices[0].message.content.lower()
47
+ except:
48
+ # Default to showing Tanzania if we can't determine
49
+ is_in_tanzania = True
50
+ else:
51
+ is_in_tanzania = True
52
+
53
+ # Now get the habitat locations
54
  prompt = f"""
55
  Provide a JSON array of the main habitat locations for the {clean_name} bird in the world.
56
  Return ONLY a JSON array with 3-5 entries, each containing:
 
65
  ...
66
  ]
67
 
68
+ {'' if is_in_tanzania else 'DO NOT include any locations in Tanzania as this bird is not native to or commonly found there.'}
69
  """
70
 
71
  try:
 
91
  else:
92
  # Fallback if JSON extraction fails
93
  locations = [
94
+ {"name": "Primary habitat region", "lat": 0, "lon": 0,
95
+ "description": "Could not retrieve specific habitat information for this bird."}
96
  ]
97
 
98
+ return locations, is_in_tanzania
99
 
100
  except Exception as e:
101
+ return [{"name": "Error retrieving data", "lat": 0, "lon": 0,
102
+ "description": "Please try again or check your connection."}], False
103
 
104
  def create_habitat_map(habitat_locations):
105
  """Create a folium map with the habitat locations"""
106
+ # Find center point based on valid coordinates
107
+ valid_coords = [(loc.get("lat", 0), loc.get("lon", 0))
108
+ for loc in habitat_locations
109
+ if loc.get("lat", 0) != 0 or loc.get("lon", 0) != 0]
110
+
111
+ if valid_coords:
112
+ # Calculate the average of the coordinates
113
+ avg_lat = sum(lat for lat, _ in valid_coords) / len(valid_coords)
114
+ avg_lon = sum(lon for _, lon in valid_coords) / len(valid_coords)
115
+ # Create map centered on the average coordinates
116
+ m = folium.Map(location=[avg_lat, avg_lon], zoom_start=3)
117
+ else:
118
+ # Default world map if no valid coordinates
119
+ m = folium.Map(location=[20, 0], zoom_start=2)
120
 
121
  # Add markers for each habitat location
122
  for location in habitat_locations:
 
140
  map_html = m._repr_html_()
141
  return map_html
142
 
143
+ def format_bird_info(raw_info):
144
+ """Improve the formatting of bird information"""
145
+ # Add proper line breaks between sections and ensure consistent heading levels
146
+ formatted = raw_info
147
+
148
+ # Fix heading levels (make all main sections h3)
149
+ formatted = re.sub(r'#+\s+NOT TYPICALLY FOUND IN TANZANIA',
150
+ '<div class="alert alert-warning"><strong>⚠️ NOT TYPICALLY FOUND IN TANZANIA</strong></div>',
151
+ formatted)
152
+
153
+ # Replace markdown headings with HTML headings for better control
154
+ formatted = re.sub(r'#+\s+(.*)', r'<h3>\1</h3>', formatted)
155
+
156
+ # Add paragraph tags for better spacing
157
+ formatted = re.sub(r'\n\*\s+(.*)', r'<p>• \1</p>', formatted)
158
+ formatted = re.sub(r'\n([^<\n].*)', r'<p>\1</p>', formatted)
159
+
160
+ # Remove any duplicate paragraph tags
161
+ formatted = formatted.replace('<p><p>', '<p>')
162
+ formatted = formatted.replace('</p></p>', '</p>')
163
+
164
+ return formatted
165
+
166
  def get_bird_info(bird_name):
167
  """Get detailed information about a bird using Groq API"""
168
  clean_name = clean_bird_name(bird_name)
 
217
  clean_top_bird = clean_bird_name(top_bird)
218
 
219
  # Get habitat locations and create map
220
+ habitat_locations, is_in_tanzania = get_bird_habitat_map(top_bird)
221
  habitat_map_html = create_habitat_map(habitat_locations)
222
 
223
  # Get detailed information about the top predicted bird
224
  bird_info = get_bird_info(top_bird)
225
+ formatted_info = format_bird_info(bird_info)
226
+
227
+ # Create combined info with map at the top and properly formatted information
228
+ custom_css = """
229
+ <style>
230
+ .bird-container {
231
+ font-family: Arial, sans-serif;
232
+ padding: 10px;
233
+ }
234
+ .map-container {
235
+ height: 400px;
236
+ width: 100%;
237
+ border: 1px solid #ddd;
238
+ border-radius: 8px;
239
+ overflow: hidden;
240
+ margin-bottom: 20px;
241
+ }
242
+ .info-container {
243
+ line-height: 1.6;
244
+ }
245
+ .info-container h3 {
246
+ margin-top: 20px;
247
+ margin-bottom: 10px;
248
+ color: #2c3e50;
249
+ border-bottom: 1px solid #eee;
250
+ padding-bottom: 5px;
251
+ }
252
+ .info-container p {
253
+ margin-bottom: 10px;
254
+ }
255
+ .alert {
256
+ padding: 10px;
257
+ margin-bottom: 15px;
258
+ border-radius: 4px;
259
+ }
260
+ .alert-warning {
261
+ background-color: #fcf8e3;
262
+ border: 1px solid #faebcc;
263
+ color: #8a6d3b;
264
+ }
265
+ </style>
266
+ """
267
 
 
268
  combined_info = f"""
269
+ {custom_css}
270
+ <div class="bird-container">
271
+ <h2>Natural Habitat Map for {clean_top_bird}</h2>
272
+ <div class="map-container">
273
+ {habitat_map_html}
274
+ </div>
275
+
276
+ <div class="info-container">
277
+ <h2>Detailed Information</h2>
278
+ {formatted_info}
279
+ </div>
280
+ </div>
281
+ """
282
 
283
  return prediction_results, combined_info, clean_top_bird
284