RubaAnam1 commited on
Commit
0769c59
·
verified ·
1 Parent(s): 7c65a3b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -54
app.py CHANGED
@@ -9,6 +9,7 @@ from urllib.parse import quote
9
 
10
  st.set_page_config(page_title="Biodiversity GIS Explorer", layout="wide")
11
  st.title("🌍 Biodiversity GIS Explorer")
 
12
 
13
  # =====================================================
14
  # GEMINI
@@ -19,10 +20,16 @@ def call_gemini(prompt, api_key):
19
  if not api_key:
20
  return "⚠️ GEMINI_API_KEY not found."
21
 
22
- url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite:generateContent?key={api_key}"
 
 
 
 
23
 
24
  payload = {
25
- "contents": [{"parts": [{"text": prompt}]}]
 
 
26
  }
27
 
28
  try:
@@ -34,57 +41,44 @@ def call_gemini(prompt, api_key):
34
 
35
 
36
  # =====================================================
37
- # COUNTRY (fixed)
38
  # =====================================================
39
 
40
  country_codes = {
41
- "sudan": "SD",
42
- "السودان": "SD",
43
- "egypt": "EG",
44
- "مصر": "EG",
45
- "kenya": "KE",
46
- "كينيا": "KE",
47
- "ethiopia": "ET",
48
- "إثيوبيا": "ET",
49
- "saudi arabia": "SA",
50
- "السعودية": "SA",
51
- "usa": "US",
52
- "united states": "US",
53
- "america": "US",
54
- "امريكا": "US",
55
- "canada": "CA",
56
- "كندا": "CA"
57
  }
58
 
59
-
60
  # =====================================================
61
- # TAXON FILTERS (FIXED - IMPORTANT)
62
  # =====================================================
63
 
64
  species_filters = {
65
- "Birds": "taxon_key=212",
66
- "Plants": "taxon_key=6",
67
- "Mammals": "taxon_key=359",
68
- "Reptiles": "taxon_key=358",
69
- "Fish": "taxon_key=204",
70
- "Insects": "taxon_key=216"
71
  }
72
 
73
-
74
  # =====================================================
75
- # GET SPECIES (CLEAN + FIXED GBIF LOGIC)
76
  # =====================================================
77
 
78
  def get_species(country_code, filter_value):
79
 
80
  url = (
81
- "https://api.gbif.org/v1/occurrence/search?"
82
  f"country={country_code}"
83
  f"&{filter_value}"
84
- "&limit=200"
85
- "&has_coordinate=true"
86
- "&has_geospatial_issue=false"
87
- "&occurrence_status=PRESENT"
88
  )
89
 
90
  try:
@@ -96,29 +90,32 @@ def get_species(country_code, filter_value):
96
 
97
  bad_words = [
98
  "unclassified", "sp.", "cf.", "aff.",
99
- "unknown", "incertae", "plant", "bird"
100
  ]
101
 
102
  for item in results:
103
 
104
- sp = item.get("species")
105
  kingdom = item.get("kingdom")
 
106
 
107
- # FILTER 1: must exist
108
  if not sp:
109
  continue
110
 
111
- # FILTER 2: remove junk names
112
  sp_low = sp.lower()
 
113
  if any(w in sp_low for w in bad_words):
114
  continue
115
 
116
- # FILTER 3: must be real species name
117
  if len(sp.split()) < 2:
118
  continue
119
 
120
- # FILTER 4: strict bird check
121
- if species_type == "Birds" and kingdom != "Animalia":
 
 
 
 
122
  continue
123
 
124
  if sp not in species:
@@ -132,7 +129,7 @@ def get_species(country_code, filter_value):
132
 
133
 
134
  # =====================================================
135
- # LINKS (kept clean)
136
  # =====================================================
137
 
138
  def get_species_links(species_name, country):
@@ -143,7 +140,6 @@ def get_species_links(species_name, country):
143
  q = quote(clean)
144
  c = quote(country)
145
 
146
- # GBIF
147
  try:
148
  r = requests.get(
149
  f"https://api.gbif.org/v1/species/match?name={q}"
@@ -156,17 +152,14 @@ def get_species_links(species_name, country):
156
  except:
157
  pass
158
 
159
- # Wikipedia
160
  links.append(
161
  f"- [Wikipedia](https://en.wikipedia.org/wiki/{clean.replace(' ','_')})"
162
  )
163
 
164
- # iNaturalist
165
  links.append(
166
  f"- [iNaturalist](https://www.inaturalist.org/search?q={q})"
167
  )
168
 
169
- # Scholar
170
  links.append(
171
  f"- [Google Scholar](https://scholar.google.com/scholar?q={q}+{c})"
172
  )
@@ -186,12 +179,12 @@ species_type = st.selectbox(
186
  )
187
 
188
  # =====================================================
189
- # MAIN
190
  # =====================================================
191
 
192
  if st.button("Search Biodiversity"):
193
 
194
- # normalize country
195
  country_clean = country.strip().lower()
196
  country_code = country_codes.get(country_clean)
197
 
@@ -205,32 +198,36 @@ if st.button("Search Biodiversity"):
205
 
206
  filter_value = species_filters[species_type]
207
 
208
- with st.spinner("Fetching GBIF data..."):
209
  species_list = get_species(country_code, filter_value)
210
 
211
  if not species_list:
212
  st.warning("No clean species found")
213
  st.stop()
214
 
 
 
 
 
215
  st.subheader("🐾 Species Found")
216
 
217
  for sp in species_list:
218
  st.write("•", sp)
219
 
220
  # =================================================
221
- # AI
222
  # =================================================
223
 
224
  prompt = f"""
225
  You are a biodiversity scientist.
226
 
227
  Country: {country}
228
- Type: {species_type}
229
 
230
- Species:
231
  {chr(10).join(species_list)}
232
 
233
- Only analyze real species.
234
  """
235
 
236
  st.subheader("🤖 AI Analysis")
@@ -246,7 +243,10 @@ Only analyze real species.
246
  st.subheader("🔗 Links")
247
 
248
  for sp in species_list:
249
- st.markdown(f"### {sp}")
 
 
250
  for link in get_species_links(sp, country):
251
  st.markdown(link)
 
252
  st.markdown("---")
 
9
 
10
  st.set_page_config(page_title="Biodiversity GIS Explorer", layout="wide")
11
  st.title("🌍 Biodiversity GIS Explorer")
12
+ st.write("Explore biodiversity species using GBIF + AI analysis")
13
 
14
  # =====================================================
15
  # GEMINI
 
20
  if not api_key:
21
  return "⚠️ GEMINI_API_KEY not found."
22
 
23
+ url = (
24
+ "https://generativelanguage.googleapis.com/v1beta/models/"
25
+ "gemini-3.1-flash-lite:generateContent?key="
26
+ f"{api_key}"
27
+ )
28
 
29
  payload = {
30
+ "contents": [
31
+ {"parts": [{"text": prompt}]}
32
+ ]
33
  }
34
 
35
  try:
 
41
 
42
 
43
  # =====================================================
44
+ # COUNTRY CLEAN INPUT
45
  # =====================================================
46
 
47
  country_codes = {
48
+ "sudan": "SD", "السودان": "SD",
49
+ "egypt": "EG", "مصر": "EG",
50
+ "kenya": "KE", "كينيا": "KE",
51
+ "ethiopia": "ET", "إثيوبيا": "ET",
52
+ "saudi arabia": "SA", "السعودية": "SA",
53
+ "usa": "US", "united states": "US", "america": "US", "امريكا": "US",
54
+ "canada": "CA", "كندا": "CA"
 
 
 
 
 
 
 
 
 
55
  }
56
 
 
57
  # =====================================================
58
+ # TAXON FILTERS (FIXED APPROACH)
59
  # =====================================================
60
 
61
  species_filters = {
62
+ "Birds": "kingdom=Animalia&class=Aves",
63
+ "Plants": "kingdom=Plantae",
64
+ "Mammals": "kingdom=Animalia&class=Mammalia",
65
+ "Reptiles": "kingdom=Animalia&class=Reptilia",
66
+ "Fish": "kingdom=Animalia&class=Actinopterygii",
67
+ "Insects": "kingdom=Animalia&class=Insecta"
68
  }
69
 
 
70
  # =====================================================
71
+ # GET CLEAN SPECIES (IMPORTANT FIX)
72
  # =====================================================
73
 
74
  def get_species(country_code, filter_value):
75
 
76
  url = (
77
+ "https://api.gbif.org/v1/species/search?"
78
  f"country={country_code}"
79
  f"&{filter_value}"
80
+ "&rank=SPECIES"
81
+ "&limit=50"
 
 
82
  )
83
 
84
  try:
 
90
 
91
  bad_words = [
92
  "unclassified", "sp.", "cf.", "aff.",
93
+ "unknown", "incertae"
94
  ]
95
 
96
  for item in results:
97
 
98
+ sp = item.get("scientificName")
99
  kingdom = item.get("kingdom")
100
+ cls = item.get("class")
101
 
 
102
  if not sp:
103
  continue
104
 
 
105
  sp_low = sp.lower()
106
+
107
  if any(w in sp_low for w in bad_words):
108
  continue
109
 
 
110
  if len(sp.split()) < 2:
111
  continue
112
 
113
+ # strict filtering
114
+ if species_type == "Birds" and cls != "Aves":
115
+ continue
116
+ if species_type == "Plants" and kingdom != "Plantae":
117
+ continue
118
+ if species_type != "Plants" and kingdom != "Animalia":
119
  continue
120
 
121
  if sp not in species:
 
129
 
130
 
131
  # =====================================================
132
+ # LINKS
133
  # =====================================================
134
 
135
  def get_species_links(species_name, country):
 
140
  q = quote(clean)
141
  c = quote(country)
142
 
 
143
  try:
144
  r = requests.get(
145
  f"https://api.gbif.org/v1/species/match?name={q}"
 
152
  except:
153
  pass
154
 
 
155
  links.append(
156
  f"- [Wikipedia](https://en.wikipedia.org/wiki/{clean.replace(' ','_')})"
157
  )
158
 
 
159
  links.append(
160
  f"- [iNaturalist](https://www.inaturalist.org/search?q={q})"
161
  )
162
 
 
163
  links.append(
164
  f"- [Google Scholar](https://scholar.google.com/scholar?q={q}+{c})"
165
  )
 
179
  )
180
 
181
  # =====================================================
182
+ # SEARCH
183
  # =====================================================
184
 
185
  if st.button("Search Biodiversity"):
186
 
187
+ # clean country input
188
  country_clean = country.strip().lower()
189
  country_code = country_codes.get(country_clean)
190
 
 
198
 
199
  filter_value = species_filters[species_type]
200
 
201
+ with st.spinner("Fetching clean GBIF species..."):
202
  species_list = get_species(country_code, filter_value)
203
 
204
  if not species_list:
205
  st.warning("No clean species found")
206
  st.stop()
207
 
208
+ # =================================================
209
+ # DISPLAY
210
+ # =================================================
211
+
212
  st.subheader("🐾 Species Found")
213
 
214
  for sp in species_list:
215
  st.write("•", sp)
216
 
217
  # =================================================
218
+ # GEMINI
219
  # =================================================
220
 
221
  prompt = f"""
222
  You are a biodiversity scientist.
223
 
224
  Country: {country}
225
+ Group: {species_type}
226
 
227
+ Species list:
228
  {chr(10).join(species_list)}
229
 
230
+ Only analyze real species. No hallucination.
231
  """
232
 
233
  st.subheader("🤖 AI Analysis")
 
243
  st.subheader("🔗 Links")
244
 
245
  for sp in species_list:
246
+
247
+ st.markdown(f"### 🔬 {sp}")
248
+
249
  for link in get_species_links(sp, country):
250
  st.markdown(link)
251
+
252
  st.markdown("---")