shukdevdatta123 commited on
Commit
ecd748a
·
verified ·
1 Parent(s): 37c6da0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -32
app.py CHANGED
@@ -10,7 +10,6 @@ import base64
10
 
11
  # Constants
12
  DEFAULT_MODEL = "opengvlab/internvl3-14b:free"
13
- # No need for placeholder text as we'll use password type input
14
  DEFAULT_SITE_URL = "https://dynamic-nature-trail-guide.app"
15
  DEFAULT_SITE_NAME = "Dynamic Nature Trail Guide"
16
 
@@ -18,15 +17,12 @@ DEFAULT_SITE_NAME = "Dynamic Nature Trail Guide"
18
  SYSTEM_PROMPT = """
19
  You are the Dynamic Nature Trail Guide, an expert in identifying and explaining natural elements
20
  found on nature trails. For any image sent, please:
21
-
22
  1. Identify all visible plants, animals, geological features, and ecosystems
23
  2. Provide educational information about identified elements
24
  3. Mention any seasonal characteristics visible in the image
25
  4. Note any ecological significance or conservation considerations
26
- 5. Offer suggestions for what to observe or learn about next on the trail
27
-
28
  Keep explanations informative yet accessible to people of all ages and backgrounds.
29
-
30
  IMPORTANT: Structure your responses with clear sections and headings.
31
  """
32
 
@@ -36,7 +32,7 @@ def encode_image_to_base64(image_path):
36
  return base64.b64encode(image_file.read()).decode('utf-8')
37
 
38
  def format_response_as_html(text):
39
- """Convert the model's text response to formatted HTML"""
40
  if not text:
41
  return ""
42
 
@@ -44,46 +40,84 @@ def format_response_as_html(text):
44
  if text.startswith("Error analyzing image:"):
45
  return f'<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 5px;">{text}</div>'
46
 
47
- # Replace newlines with HTML breaks
48
- text = text.replace('\n\n', '</p><p>').replace('\n', '<br>')
 
49
 
50
- # Handle headings - look for patterns like "1. Identification:" or "Species Identified:"
51
- heading_patterns = [
52
- (r'([A-Za-z\s]+):(?=<br>|</p>)', r'<h3>\1</h3>'), # "Category:" at start of line
53
- (r'(\d+\.\s+[A-Za-z\s]+):(?=<br>|</p>)', r'<h3>\1</h3>'), # "1. Category:" format
54
- ]
55
 
56
- for pattern, replacement in heading_patterns:
57
- text = re.sub(pattern, replacement, text)
58
 
59
- # Enhance species names with bold
60
- text = re.sub(r'\b([A-Z][a-z]+\s+[a-z]+)\b(?!\<\/)', r'<strong>\1</strong>', text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  # Add some color to certain keywords
63
  color_mappings = {
64
- 'endangered': 'red',
65
  'rare': '#FF6600',
66
- 'native': '#006600',
67
  'invasive': '#CC0000',
68
- 'ecosystem': '#006699',
69
  'habitat': '#336699',
 
 
 
70
  }
71
 
72
  for keyword, color in color_mappings.items():
73
- text = re.sub(r'\b' + keyword + r'\b', f'<span style="color: {color};">{keyword}</span>', text, flags=re.IGNORECASE)
74
-
75
- # Wrap the entire content in a styled div
76
- html = f'''
77
- <div style="padding: 15px; font-family: Arial, sans-serif; line-height: 1.6;">
78
- <p>{text}</p>
79
- </div>
80
- '''
81
 
82
- return html
 
 
 
 
 
 
83
 
84
  def analyze_image(api_key, image, prompt="What can you identify in this nature trail image? Provide detailed educational information.", site_url=DEFAULT_SITE_URL, site_name=DEFAULT_SITE_NAME, model=DEFAULT_MODEL):
85
  """Analyze the uploaded image using the InternVL3 model via OpenRouter"""
86
- # Remove the placeholder text check
87
  if not api_key:
88
  return "<div style='color: red; padding: 10px; border: 1px solid red; border-radius: 5px;'>Please provide an OpenRouter API key.</div>"
89
 
@@ -276,5 +310,4 @@ def create_interface():
276
 
277
  # Create and launch the app
278
  if __name__ == "__main__":
279
- app = create_interface()
280
- app.launch()
 
10
 
11
  # Constants
12
  DEFAULT_MODEL = "opengvlab/internvl3-14b:free"
 
13
  DEFAULT_SITE_URL = "https://dynamic-nature-trail-guide.app"
14
  DEFAULT_SITE_NAME = "Dynamic Nature Trail Guide"
15
 
 
17
  SYSTEM_PROMPT = """
18
  You are the Dynamic Nature Trail Guide, an expert in identifying and explaining natural elements
19
  found on nature trails. For any image sent, please:
 
20
  1. Identify all visible plants, animals, geological features, and ecosystems
21
  2. Provide educational information about identified elements
22
  3. Mention any seasonal characteristics visible in the image
23
  4. Note any ecological significance or conservation considerations
24
+ 5. Offer suggestions for what to observe or learn next on the trail
 
25
  Keep explanations informative yet accessible to people of all ages and backgrounds.
 
26
  IMPORTANT: Structure your responses with clear sections and headings.
27
  """
28
 
 
32
  return base64.b64encode(image_file.read()).decode('utf-8')
33
 
34
  def format_response_as_html(text):
35
+ """Convert the model's text response to formatted HTML with improved section handling"""
36
  if not text:
37
  return ""
38
 
 
40
  if text.startswith("Error analyzing image:"):
41
  return f'<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 5px;">{text}</div>'
42
 
43
+ # Parse sections using regex patterns
44
+ # Look for patterns like "### 1. Identification of Elements" or "## Plants:"
45
+ sections = re.split(r'(?:#{1,3}\s*\d*\.?\s*|\*\*)([\w\s]+)(?:\*\*|:)', text)
46
 
47
+ # If splitting didn't work well, fall back to a simpler approach
48
+ if len(sections) <= 1:
49
+ # Simple formatting with paragraphs
50
+ text = text.replace('\n\n', '</p><p>')
51
+ return f'<div style="padding: 15px; font-family: Arial, sans-serif; line-height: 1.6;"><p>{text}</p></div>'
52
 
53
+ # Build HTML from sections
54
+ html_parts = ['<div style="padding: 15px; font-family: Arial, sans-serif; line-height: 1.6;">']
55
 
56
+ for i in range(1, len(sections), 2):
57
+ if i < len(sections) - 1:
58
+ section_title = sections[i].strip()
59
+ section_content = sections[i+1].strip()
60
+
61
+ # Apply formatting to section content
62
+ section_content = format_section_content(section_content)
63
+
64
+ html_parts.append(f'<div class="section">')
65
+ html_parts.append(f'<h3 style="color: #336699; border-bottom: 1px solid #ccc; padding-bottom: 5px;">{section_title}</h3>')
66
+ html_parts.append(f'<div class="content">{section_content}</div>')
67
+ html_parts.append('</div>')
68
+
69
+ # If we couldn't parse sections properly, use the original text
70
+ if len(html_parts) == 1:
71
+ text = format_section_content(text)
72
+ html_parts.append(f'<p>{text}</p>')
73
+
74
+ html_parts.append('</div>')
75
+ return ''.join(html_parts)
76
+
77
+ def format_section_content(content):
78
+ """Format the content of a section with enhanced styling"""
79
+ # Replace line breaks with paragraph breaks for better readability
80
+ content = re.sub(r'\n\s*\n', '</p><p>', content)
81
+ content = re.sub(r'\n(?!<\/p>)', '<br>', content)
82
+
83
+ # Convert bullet points
84
+ content = re.sub(r'^\s*-\s*(.+?)$', r'<li>\1</li>', content, flags=re.MULTILINE)
85
+ content = re.sub(r'(<li>.*?</li>)', r'<ul>\1</ul>', content, flags=re.DOTALL)
86
+ # Fix nested lists (remove empty ul tags)
87
+ content = re.sub(r'<ul>\s*</ul>', '', content)
88
+
89
+ # Handle subsections like "**Plants:**"
90
+ content = re.sub(r'\*\*([\w\s]+):\*\*', r'<h4 style="margin-bottom: 5px; color: #336699;">\1</h4>', content)
91
+
92
+ # Enhance species names with bold and italics for scientific names
93
+ content = re.sub(r'\b([A-Z][a-z]+\s+[a-z]+)\b(?!\<\/)', r'<strong><em>\1</em></strong>', content)
94
 
95
  # Add some color to certain keywords
96
  color_mappings = {
97
+ 'endangered': '#e74c3c',
98
  'rare': '#FF6600',
99
+ 'native': '#27ae60',
100
  'invasive': '#CC0000',
101
+ 'ecosystem': '#3498db',
102
  'habitat': '#336699',
103
+ 'conservation': '#16a085',
104
+ 'protected': '#9b59b6',
105
+ 'biodiversity': '#2ecc71'
106
  }
107
 
108
  for keyword, color in color_mappings.items():
109
+ content = re.sub(r'\b' + keyword + r'\b', f'<span style="color: {color}; font-weight: bold;">{keyword}</span>', content, flags=re.IGNORECASE)
 
 
 
 
 
 
 
110
 
111
+ # Ensure the content starts and ends with paragraph tags if needed
112
+ if not content.startswith('<p>') and not content.startswith('<ul>') and not content.startswith('<h4'):
113
+ content = '<p>' + content
114
+ if not content.endswith('</p>') and not content.endswith('</ul>'):
115
+ content = content + '</p>'
116
+
117
+ return content
118
 
119
  def analyze_image(api_key, image, prompt="What can you identify in this nature trail image? Provide detailed educational information.", site_url=DEFAULT_SITE_URL, site_name=DEFAULT_SITE_NAME, model=DEFAULT_MODEL):
120
  """Analyze the uploaded image using the InternVL3 model via OpenRouter"""
 
121
  if not api_key:
122
  return "<div style='color: red; padding: 10px; border: 1px solid red; border-radius: 5px;'>Please provide an OpenRouter API key.</div>"
123
 
 
310
 
311
  # Create and launch the app
312
  if __name__ == "__main__":
313
+ app = create_interface()