Jacksonnavigator7 commited on
Commit
1246a0b
·
verified ·
1 Parent(s): 4412aef

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -221
app.py CHANGED
@@ -15,46 +15,6 @@ client = Groq(
15
  api_key=os.environ.get("GROQ_API_KEY"),
16
  )
17
 
18
- # Language translations
19
- translations = {
20
- "en": {
21
- "app_title": "Bird Species Identification for Researchers",
22
- "app_description": "Upload an image to identify bird species and get detailed information relevant to research in Tanzania and climate change studies.",
23
- "upload_label": "Upload Bird Image",
24
- "identify_button": "Identify Bird",
25
- "predictions_label": "Top 5 Predictions",
26
- "bird_info_label": "Bird Information",
27
- "research_questions": "Research Questions",
28
- "question_placeholder": "Example: How has climate change affected this bird's migration pattern?",
29
- "question_label": "Ask a question about this bird",
30
- "submit_question": "Submit Question",
31
- "clear_conversation": "Clear Conversation",
32
- "upload_prompt": "Please upload an image",
33
- "question_title": "Question:",
34
- "answer_title": "Answer:",
35
- "habitat_map_title": "Natural Habitat Map for",
36
- "detailed_info_title": "Detailed Information"
37
- },
38
- "sw": {
39
- "app_title": "Utambuzi wa Spishi za Ndege kwa Watafiti",
40
- "app_description": "Pakia picha ili kutambua spishi za ndege na kupata taarifa muhimu zinazohusiana na utafiti nchini Tanzania na masomo ya mabadiliko ya tabianchi.",
41
- "upload_label": "Pakia Picha ya Ndege",
42
- "identify_button": "Tambua Ndege",
43
- "predictions_label": "Utabiri Bora 5",
44
- "bird_info_label": "Taarifa za Ndege",
45
- "research_questions": "Maswali ya Utafiti",
46
- "question_placeholder": "Mfano: Je, mabadiliko ya tabianchi yameathiri vipi mfumo wa uhamiaji wa ndege huyu?",
47
- "question_label": "Uliza swali kuhusu ndege huyu",
48
- "submit_question": "Wasilisha Swali",
49
- "clear_conversation": "Futa Mazungumzo",
50
- "upload_prompt": "Tafadhali pakia picha",
51
- "question_title": "Swali:",
52
- "answer_title": "Jibu:",
53
- "habitat_map_title": "Ramani ya Makazi Asilia ya",
54
- "detailed_info_title": "Taarifa za Kina"
55
- }
56
- }
57
-
58
  def clean_bird_name(name):
59
  """Clean bird name by removing numbers and special characters, and fix formatting"""
60
  # Remove numbers and dots at the beginning
@@ -180,18 +140,14 @@ def create_habitat_map(habitat_locations):
180
  map_html = m._repr_html_()
181
  return map_html
182
 
183
- def format_bird_info(raw_info, language="en"):
184
  """Improve the formatting of bird information"""
185
  # Add proper line breaks between sections and ensure consistent heading levels
186
  formatted = raw_info
187
 
188
- # Get translation of warning text based on language
189
- warning_text = "NOT TYPICALLY FOUND IN TANZANIA"
190
- warning_translation = "HAPATIKANI SANA TANZANIA" if language == "sw" else warning_text
191
-
192
  # Fix heading levels (make all main sections h3)
193
- formatted = re.sub(r'#+\s+' + warning_text,
194
- f'<div class="alert alert-warning"><strong>⚠️ {warning_translation}</strong></div>',
195
  formatted)
196
 
197
  # Replace markdown headings with HTML headings for better control
@@ -207,15 +163,10 @@ def format_bird_info(raw_info, language="en"):
207
 
208
  return formatted
209
 
210
- def get_bird_info(bird_name, language="en"):
211
  """Get detailed information about a bird using Groq API"""
212
  clean_name = clean_bird_name(bird_name)
213
 
214
- # Adjust language for the prompt
215
- lang_instruction = ""
216
- if language == "sw":
217
- lang_instruction = " Provide your response in Swahili language."
218
-
219
  prompt = f"""
220
  Provide detailed information about the {clean_name} bird, including:
221
  1. Physical characteristics and appearance
@@ -226,7 +177,7 @@ def get_bird_info(bird_name, language="en"):
226
 
227
  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.
228
 
229
- Format your response in markdown for better readability.{lang_instruction}
230
  """
231
 
232
  try:
@@ -241,14 +192,10 @@ def get_bird_info(bird_name, language="en"):
241
  )
242
  return chat_completion.choices[0].message.content
243
  except Exception as e:
244
- error_msg = "Hitilafu katika kupata taarifa" if language == "sw" else "Error fetching information"
245
- return f"{error_msg}: {str(e)}"
246
 
247
- def predict_and_get_info(img, language="en"):
248
  """Predict bird species and get detailed information"""
249
- # Get translations
250
- t = translations[language]
251
-
252
  # Process the image
253
  img = PILImage.create(img)
254
 
@@ -274,8 +221,8 @@ def predict_and_get_info(img, language="en"):
274
  habitat_map_html = create_habitat_map(habitat_locations)
275
 
276
  # Get detailed information about the top predicted bird
277
- bird_info = get_bird_info(top_bird, language)
278
- formatted_info = format_bird_info(bird_info, language)
279
 
280
  # Create combined info with map at the top and properly formatted information
281
  custom_css = """
@@ -321,13 +268,13 @@ def predict_and_get_info(img, language="en"):
321
  combined_info = f"""
322
  {custom_css}
323
  <div class="bird-container">
324
- <h2>{t['habitat_map_title']} {clean_top_bird}</h2>
325
  <div class="map-container">
326
  {habitat_map_html}
327
  </div>
328
 
329
  <div class="info-container">
330
- <h2>{t['detailed_info_title']}</h2>
331
  {formatted_info}
332
  </div>
333
  </div>
@@ -335,17 +282,10 @@ def predict_and_get_info(img, language="en"):
335
 
336
  return prediction_results, combined_info, clean_top_bird
337
 
338
- def follow_up_question(question, bird_name, language="en"):
339
  """Allow researchers to ask follow-up questions about the identified bird"""
340
- t = translations[language]
341
-
342
  if not question.strip() or not bird_name:
343
- return "Please identify a bird first and ask a specific question about it." if language == "en" else "Tafadhali tambua ndege kwanza na uulize swali maalum kuhusu ndege huyo."
344
-
345
- # Adjust language for the prompt
346
- lang_instruction = ""
347
- if language == "sw":
348
- lang_instruction = " Provide your response in Swahili language."
349
 
350
  prompt = f"""
351
  The researcher is asking about the {bird_name} bird: "{question}"
@@ -357,7 +297,7 @@ def follow_up_question(question, bird_name, language="en"):
357
  Do not start your answer with phrases like "Introduction to the {bird_name}" or similar repetitive headers.
358
  Directly answer the specific question asked.
359
 
360
- Format your response in markdown for better readability.{lang_instruction}
361
  """
362
 
363
  try:
@@ -372,159 +312,95 @@ def follow_up_question(question, bird_name, language="en"):
372
  )
373
  return chat_completion.choices[0].message.content
374
  except Exception as e:
375
- error_msg = "Hitilafu katika kupata taarifa" if language == "sw" else "Error fetching information"
376
- return f"{error_msg}: {str(e)}"
377
 
378
- def update_conversation(question, bird_name, history, language="en"):
379
- """Update the conversation history with new Q&A"""
380
- t = translations[language]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
 
382
- if not question.strip():
383
- return history
384
 
385
- answer = follow_up_question(question, bird_name, language)
 
386
 
387
- # Format the conversation with clear separation
388
- new_exchange = f"""
389
- ### {t['question_title']}
390
- {question}
391
- ### {t['answer_title']}
392
- {answer}
393
- ---
394
- """
395
- updated_history = new_exchange + history
396
- return updated_history
397
-
398
- # Create the Gradio interface
399
- def create_interface(language="en"):
400
- t = translations[language]
401
-
402
- with gr.Blocks(theme=gr.themes.Soft()) as app:
403
- # Language selector
404
- with gr.Row():
405
- with gr.Column(scale=3):
406
- gr.Markdown(f"# {t['app_title']}")
407
- with gr.Column(scale=1):
408
- language_selector = gr.Radio(
409
- choices=["English", "Kiswahili"],
410
- label="Language / Lugha",
411
- value="English" if language == "en" else "Kiswahili"
412
- )
413
-
414
- gr.Markdown(f"{t['app_description']}")
415
-
416
- # Store the current bird and language for context
417
- current_bird = gr.State("")
418
- current_lang = gr.State(language)
419
-
420
- # Main identification section
421
- with gr.Row():
422
- with gr.Column(scale=1):
423
- input_image = gr.Image(type="pil", label=t['upload_label'])
424
- submit_btn = gr.Button(t['identify_button'], variant="primary")
425
-
426
- with gr.Column(scale=2):
427
- prediction_output = gr.Label(label=t['predictions_label'], num_top_classes=5)
428
- bird_info_output = gr.HTML(label=t['bird_info_label'])
429
-
430
- # Clear divider
431
- gr.Markdown("---")
432
-
433
- # Follow-up question section with improved UI
434
- gr.Markdown(f"## {t['research_questions']}")
435
-
436
- conversation_history = gr.Markdown("")
437
-
438
- with gr.Row():
439
- follow_up_input = gr.Textbox(
440
- label=t['question_label'],
441
- placeholder=t['question_placeholder'],
442
- lines=2
443
- )
444
-
445
- with gr.Row():
446
- follow_up_btn = gr.Button(t['submit_question'], variant="primary")
447
- clear_btn = gr.Button(t['clear_conversation'])
448
-
449
- # Set up event handlers
450
- def process_image(img, lang):
451
- if img is None:
452
- return None, translations[lang]['upload_prompt'], "", ""
453
-
454
- try:
455
- pred_results, info, clean_bird_name = predict_and_get_info(img, lang)
456
- return pred_results, info, clean_bird_name, ""
457
- except Exception as e:
458
- error_msg = "Hitilafu katika kuchakata picha" if lang == "sw" else "Error processing image"
459
- return None, f"{error_msg}: {str(e)}", "", ""
460
-
461
- def clear_conversation_history():
462
- return ""
463
-
464
- def switch_language(choice):
465
- new_lang = "sw" if choice == "Kiswahili" else "en"
466
- return new_lang
467
-
468
- # Connect language selector to recreate the interface
469
- language_selector.change(
470
- switch_language,
471
- inputs=[language_selector],
472
- outputs=[current_lang]
473
- ).then(
474
- lambda lang: gr.Blocks.update(visible=False),
475
- inputs=[current_lang],
476
- outputs=[app]
477
- ).then(
478
- lambda: None,
479
- None,
480
- None,
481
- _js=f"""() => {{
482
- // Reload the page with the new language parameter
483
- const url = new URL(window.location.href);
484
- const lang = document.querySelector('input[name="language-selector"]:checked').value;
485
- url.searchParams.set('language', lang === 'Kiswahili' ? 'sw' : 'en');
486
- window.location.href = url.toString();
487
- }}"""
488
- )
489
-
490
- submit_btn.click(
491
- process_image,
492
- inputs=[input_image, current_lang],
493
- outputs=[prediction_output, bird_info_output, current_bird, conversation_history]
494
  )
 
 
 
 
 
 
 
 
 
495
 
496
- follow_up_btn.click(
497
- update_conversation,
498
- inputs=[follow_up_input, current_bird, conversation_history, current_lang],
499
- outputs=[conversation_history]
500
- ).then(
501
- lambda: "",
502
- outputs=follow_up_input
503
- )
 
504
 
505
- clear_btn.click(
506
- clear_conversation_history,
507
- outputs=[conversation_history]
508
- )
509
 
510
- return app
511
-
512
- # Get language from URL parameter or default to English
513
- def launch_app():
514
- import sys
515
-
516
- # Check if running in Gradio's development environment
517
- if len(sys.argv) > 1 and sys.argv[1] == "run":
518
- # Default to English when running locally
519
- language = "en"
520
- else:
521
- # Get language from URL parameter
522
- import os
523
- language_param = os.environ.get("GRADIO_LANGUAGE", "en")
524
- language = language_param if language_param in ["en", "sw"] else "en"
525
-
526
- app = create_interface(language)
527
- app.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
 
529
- if __name__ == "__main__":
530
- launch_app()
 
15
  api_key=os.environ.get("GROQ_API_KEY"),
16
  )
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  def clean_bird_name(name):
19
  """Clean bird name by removing numbers and special characters, and fix formatting"""
20
  # Remove numbers and dots at the beginning
 
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
 
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)
169
 
 
 
 
 
 
170
  prompt = f"""
171
  Provide detailed information about the {clean_name} bird, including:
172
  1. Physical characteristics and appearance
 
177
 
178
  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.
179
 
180
+ Format your response in markdown for better readability.
181
  """
182
 
183
  try:
 
192
  )
193
  return chat_completion.choices[0].message.content
194
  except Exception as e:
195
+ return f"Error fetching information: {str(e)}"
 
196
 
197
+ def predict_and_get_info(img):
198
  """Predict bird species and get detailed information"""
 
 
 
199
  # Process the image
200
  img = PILImage.create(img)
201
 
 
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 = """
 
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>
 
282
 
283
  return prediction_results, combined_info, clean_top_bird
284
 
285
+ def follow_up_question(question, bird_name):
286
  """Allow researchers to ask follow-up questions about the identified bird"""
 
 
287
  if not question.strip() or not bird_name:
288
+ return "Please identify a bird first and ask a specific question about it."
 
 
 
 
 
289
 
290
  prompt = f"""
291
  The researcher is asking about the {bird_name} bird: "{question}"
 
297
  Do not start your answer with phrases like "Introduction to the {bird_name}" or similar repetitive headers.
298
  Directly answer the specific question asked.
299
 
300
+ Format your response in markdown for better readability.
301
  """
302
 
303
  try:
 
312
  )
313
  return chat_completion.choices[0].message.content
314
  except Exception as e:
315
+ return f"Error fetching information: {str(e)}"
 
316
 
317
+ # Create the Gradio interface
318
+ with gr.Blocks(theme=gr.themes.Soft()) as app:
319
+ gr.Markdown("# Bird Species Identification for Researchers")
320
+ gr.Markdown("Upload an image to identify bird species and get detailed information relevant to research in Tanzania and climate change studies.")
321
+
322
+ # Store the current bird for context
323
+ current_bird = gr.State("")
324
+
325
+ # Main identification section
326
+ with gr.Row():
327
+ with gr.Column(scale=1):
328
+ input_image = gr.Image(type="pil", label="Upload Bird Image")
329
+ submit_btn = gr.Button("Identify Bird", variant="primary")
330
+
331
+ with gr.Column(scale=2):
332
+ prediction_output = gr.Label(label="Top 5 Predictions", num_top_classes=5)
333
+ bird_info_output = gr.HTML(label="Bird Information")
334
 
335
+ # Clear divider
336
+ gr.Markdown("---")
337
 
338
+ # Follow-up question section with improved UI
339
+ gr.Markdown("## Research Questions")
340
 
341
+ conversation_history = gr.Markdown("")
342
+
343
+ with gr.Row():
344
+ follow_up_input = gr.Textbox(
345
+ label="Ask a question about this bird",
346
+ placeholder="Example: How has climate change affected this bird's migration pattern?",
347
+ lines=2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  )
349
+
350
+ with gr.Row():
351
+ follow_up_btn = gr.Button("Submit Question", variant="primary")
352
+ clear_btn = gr.Button("Clear Conversation")
353
+
354
+ # Set up event handlers
355
+ def process_image(img):
356
+ if img is None:
357
+ return None, "Please upload an image", "", ""
358
 
359
+ try:
360
+ pred_results, info, clean_bird_name = predict_and_get_info(img)
361
+ return pred_results, info, clean_bird_name, ""
362
+ except Exception as e:
363
+ return None, f"Error processing image: {str(e)}", "", ""
364
+
365
+ def update_conversation(question, bird_name, history):
366
+ if not question.strip():
367
+ return history
368
 
369
+ answer = follow_up_question(question, bird_name)
 
 
 
370
 
371
+ # Format the conversation with clear separation
372
+ new_exchange = f"""
373
+ ### Question:
374
+ {question}
375
+ ### Answer:
376
+ {answer}
377
+ ---
378
+ """
379
+ updated_history = new_exchange + history
380
+ return updated_history
381
+
382
+ def clear_conversation_history():
383
+ return ""
384
+
385
+ submit_btn.click(
386
+ process_image,
387
+ inputs=[input_image],
388
+ outputs=[prediction_output, bird_info_output, current_bird, conversation_history]
389
+ )
390
+
391
+ follow_up_btn.click(
392
+ update_conversation,
393
+ inputs=[follow_up_input, current_bird, conversation_history],
394
+ outputs=[conversation_history]
395
+ ).then(
396
+ lambda: "",
397
+ outputs=follow_up_input
398
+ )
399
+
400
+ clear_btn.click(
401
+ clear_conversation_history,
402
+ outputs=[conversation_history]
403
+ )
404
 
405
+ # Launch the app
406
+ app.launch(share=True)