RubaAnam1 commited on
Commit
5d2d4b5
·
verified ·
1 Parent(s): 2386180

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -67
app.py CHANGED
@@ -9,16 +9,15 @@ 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
- st.write("Explore biodiversity species using GBIF + AI analysis")
13
 
14
  # =====================================================
15
- # GEMINI
16
  # =====================================================
17
 
18
  def call_gemini(prompt, api_key):
19
 
20
  if not api_key:
21
- return "⚠️ GEMINI_API_KEY not found."
22
 
23
  url = (
24
  "https://generativelanguage.googleapis.com/v1beta/models/"
@@ -27,21 +26,25 @@ def call_gemini(prompt, api_key):
27
  )
28
 
29
  payload = {
30
- "contents": [
31
- {"parts": [{"text": prompt}]}
32
- ]
33
  }
34
 
35
  try:
36
  r = requests.post(url, json=payload)
37
  data = r.json()
 
 
 
 
 
38
  return data["candidates"][0]["content"]["parts"][0]["text"]
 
39
  except Exception as e:
40
- return f"Gemini Error: {e}"
41
 
42
 
43
  # =====================================================
44
- # COUNTRY NORMALIZATION
45
  # =====================================================
46
 
47
  country_codes = {
@@ -50,22 +53,14 @@ country_codes = {
50
  "egypt": "EG",
51
  "مصر": "EG",
52
  "kenya": "KE",
53
- "كينيا": "KE",
54
  "ethiopia": "ET",
55
- "إثيوبيا": "ET",
56
- "saudi arabia": "SA",
57
- "السعودية": "SA",
58
  "usa": "US",
59
- "united states": "US",
60
- "america": "US",
61
- "امريكا": "US",
62
- "canada": "CA",
63
- "كندا": "CA"
64
  }
65
 
66
 
67
  # =====================================================
68
- # FILTERS (FIXED)
69
  # =====================================================
70
 
71
  species_filters = {
@@ -79,17 +74,16 @@ species_filters = {
79
 
80
 
81
  # =====================================================
82
- # GET SPECIES (WORKING VERSION)
83
  # =====================================================
84
 
85
- def get_species(country_code, filter_value):
86
 
87
  url = (
88
  "https://api.gbif.org/v1/occurrence/search?"
89
  f"country={country_code}"
90
  f"&{filter_value}"
91
  "&limit=200"
92
- "&has_coordinate=true"
93
  "&occurrence_status=PRESENT"
94
  )
95
 
@@ -100,28 +94,35 @@ def get_species(country_code, filter_value):
100
 
101
  species = []
102
 
103
- bad_words = [
104
- "unclassified", "sp.", "cf.", "aff.",
105
- "unknown", "incertae", "cf", "sp"
106
- ]
107
 
108
  for item in results:
109
 
110
  sp = item.get("species")
 
 
111
 
112
  if not sp:
113
  continue
114
 
115
  sp_low = sp.lower()
116
 
117
- # clean junk names
118
- if any(w in sp_low for w in bad_words):
119
  continue
120
 
121
- # must be binomial name
122
  if len(sp.split()) < 2:
123
  continue
124
 
 
 
 
 
 
 
 
 
 
 
125
  if sp not in species:
126
  species.append(sp)
127
 
@@ -138,13 +139,12 @@ def get_species(country_code, filter_value):
138
 
139
  def get_species_links(species_name, country):
140
 
141
- links = []
142
-
143
  clean = " ".join(species_name.split()[:2])
144
  q = quote(clean)
145
  c = quote(country)
146
 
147
- # GBIF
 
148
  try:
149
  r = requests.get(
150
  f"https://api.gbif.org/v1/species/match?name={q}"
@@ -157,20 +157,9 @@ def get_species_links(species_name, country):
157
  except:
158
  pass
159
 
160
- # Wikipedia
161
- links.append(
162
- f"- [Wikipedia](https://en.wikipedia.org/wiki/{clean.replace(' ','_')})"
163
- )
164
-
165
- # iNaturalist
166
- links.append(
167
- f"- [iNaturalist](https://www.inaturalist.org/search?q={q})"
168
- )
169
-
170
- # Google Scholar
171
- links.append(
172
- f"- [Google Scholar](https://scholar.google.com/scholar?q={q}+{c})"
173
- )
174
 
175
  return links
176
 
@@ -187,43 +176,34 @@ species_type = st.selectbox(
187
  )
188
 
189
  # =====================================================
190
- # MAIN BUTTON
191
  # =====================================================
192
 
193
  if st.button("Search Biodiversity"):
194
 
195
- # normalize input
196
  country_clean = country.strip().lower()
197
  country_code = country_codes.get(country_clean)
198
 
199
- if not country:
200
- st.warning("Please enter a country")
201
- st.stop()
202
-
203
  if not country_code:
204
- st.error(f"Country '{country}' not supported yet")
205
  st.stop()
206
 
207
  filter_value = species_filters[species_type]
208
 
209
- with st.spinner("Fetching biodiversity data..."):
210
- species_list = get_species(country_code, filter_value)
211
 
212
  if not species_list:
213
- st.warning("No species found (try another filter or country)")
214
  st.stop()
215
 
216
- # =================================================
217
- # DISPLAY
218
- # =================================================
219
-
220
  st.subheader("🐾 Species Found")
221
 
222
  for sp in species_list:
223
  st.write("•", sp)
224
 
225
  # =================================================
226
- # AI
227
  # =================================================
228
 
229
  prompt = f"""
@@ -235,14 +215,12 @@ Group: {species_type}
235
  Species:
236
  {chr(10).join(species_list)}
237
 
238
- Give ecological and GIS analysis only for real species.
239
  """
240
 
241
  st.subheader("🤖 AI Analysis")
242
 
243
- st.write(
244
- call_gemini(prompt, os.getenv("GEMINI_API_KEY"))
245
- )
246
 
247
  # =================================================
248
  # LINKS
@@ -251,10 +229,7 @@ Give ecological and GIS analysis only for real species.
251
  st.subheader("🔗 Links")
252
 
253
  for sp in species_list:
254
-
255
  st.markdown(f"### 🔬 {sp}")
256
-
257
  for link in get_species_links(sp, country):
258
  st.markdown(link)
259
-
260
  st.markdown("---")
 
9
 
10
  st.set_page_config(page_title="Biodiversity GIS Explorer", layout="wide")
11
  st.title("🌍 Biodiversity GIS Explorer")
 
12
 
13
  # =====================================================
14
+ # GEMINI (FIXED SAFE PARSING)
15
  # =====================================================
16
 
17
  def call_gemini(prompt, api_key):
18
 
19
  if not api_key:
20
+ return "⚠️ Missing API Key"
21
 
22
  url = (
23
  "https://generativelanguage.googleapis.com/v1beta/models/"
 
26
  )
27
 
28
  payload = {
29
+ "contents": [{"parts": [{"text": prompt}]}]
 
 
30
  }
31
 
32
  try:
33
  r = requests.post(url, json=payload)
34
  data = r.json()
35
+
36
+ # SAFE CHECK
37
+ if "candidates" not in data:
38
+ return f"Gemini Error: {data}"
39
+
40
  return data["candidates"][0]["content"]["parts"][0]["text"]
41
+
42
  except Exception as e:
43
+ return f"Gemini Exception: {e}"
44
 
45
 
46
  # =====================================================
47
+ # COUNTRY
48
  # =====================================================
49
 
50
  country_codes = {
 
53
  "egypt": "EG",
54
  "مصر": "EG",
55
  "kenya": "KE",
 
56
  "ethiopia": "ET",
 
 
 
57
  "usa": "US",
58
+ "america": "US"
 
 
 
 
59
  }
60
 
61
 
62
  # =====================================================
63
+ # FIXED FILTERS (IMPORTANT)
64
  # =====================================================
65
 
66
  species_filters = {
 
74
 
75
 
76
  # =====================================================
77
+ # CLEAN GBIF (STRICT FILTERING)
78
  # =====================================================
79
 
80
+ def get_species(country_code, filter_value, species_type):
81
 
82
  url = (
83
  "https://api.gbif.org/v1/occurrence/search?"
84
  f"country={country_code}"
85
  f"&{filter_value}"
86
  "&limit=200"
 
87
  "&occurrence_status=PRESENT"
88
  )
89
 
 
94
 
95
  species = []
96
 
97
+ bad = ["sp.", "cf.", "aff.", "unclassified", "unknown"]
 
 
 
98
 
99
  for item in results:
100
 
101
  sp = item.get("species")
102
+ kingdom = item.get("kingdom")
103
+ cls = item.get("class")
104
 
105
  if not sp:
106
  continue
107
 
108
  sp_low = sp.lower()
109
 
110
+ if any(b in sp_low for b in bad):
 
111
  continue
112
 
 
113
  if len(sp.split()) < 2:
114
  continue
115
 
116
+ # STRICT FILTER (FIX FOR YOUR PROBLEM)
117
+ if species_type == "Birds" and cls != "Aves":
118
+ continue
119
+
120
+ if species_type == "Plants" and kingdom != "Plantae":
121
+ continue
122
+
123
+ if species_type != "Plants" and kingdom != "Animalia":
124
+ continue
125
+
126
  if sp not in species:
127
  species.append(sp)
128
 
 
139
 
140
  def get_species_links(species_name, country):
141
 
 
 
142
  clean = " ".join(species_name.split()[:2])
143
  q = quote(clean)
144
  c = quote(country)
145
 
146
+ links = []
147
+
148
  try:
149
  r = requests.get(
150
  f"https://api.gbif.org/v1/species/match?name={q}"
 
157
  except:
158
  pass
159
 
160
+ links.append(f"- [Wikipedia](https://en.wikipedia.org/wiki/{clean.replace(' ','_')})")
161
+ links.append(f"- [iNaturalist](https://www.inaturalist.org/search?q={q})")
162
+ links.append(f"- [Google Scholar](https://scholar.google.com/scholar?q={q}+{c})")
 
 
 
 
 
 
 
 
 
 
 
163
 
164
  return links
165
 
 
176
  )
177
 
178
  # =====================================================
179
+ # RUN
180
  # =====================================================
181
 
182
  if st.button("Search Biodiversity"):
183
 
 
184
  country_clean = country.strip().lower()
185
  country_code = country_codes.get(country_clean)
186
 
 
 
 
 
187
  if not country_code:
188
+ st.error("Country not supported")
189
  st.stop()
190
 
191
  filter_value = species_filters[species_type]
192
 
193
+ with st.spinner("Fetching clean biodiversity data..."):
194
+ species_list = get_species(country_code, filter_value, species_type)
195
 
196
  if not species_list:
197
+ st.warning("No clean species found")
198
  st.stop()
199
 
 
 
 
 
200
  st.subheader("🐾 Species Found")
201
 
202
  for sp in species_list:
203
  st.write("•", sp)
204
 
205
  # =================================================
206
+ # AI FIXED
207
  # =================================================
208
 
209
  prompt = f"""
 
215
  Species:
216
  {chr(10).join(species_list)}
217
 
218
+ Only use real species. No hallucination.
219
  """
220
 
221
  st.subheader("🤖 AI Analysis")
222
 
223
+ st.write(call_gemini(prompt, os.getenv("GEMINI_API_KEY")))
 
 
224
 
225
  # =================================================
226
  # LINKS
 
229
  st.subheader("🔗 Links")
230
 
231
  for sp in species_list:
 
232
  st.markdown(f"### 🔬 {sp}")
 
233
  for link in get_species_links(sp, country):
234
  st.markdown(link)
 
235
  st.markdown("---")