annikwag commited on
Commit
71c5114
·
verified ·
1 Parent(s): 4a94065

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -36
app.py CHANGED
@@ -39,7 +39,6 @@ from appStore.crs_utils import lookup_crs_value
39
  ###########################################
40
  # Model Config
41
  ###########################################
42
-
43
  config = configparser.ConfigParser()
44
  config.read('model_params.cfg')
45
 
@@ -123,13 +122,28 @@ country_name_mapping, iso_code_to_sub_region = get_country_name_and_region_mappi
123
  )
124
  unique_country_names = sorted(country_name_mapping.keys())
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  ###########################################
127
  # Filter Controls - Row 1
128
  ###########################################
129
  col1, col2, col3, col4, col5 = st.columns([1, 1, 1, 1, 1])
130
 
131
  with col1:
132
- region_filter = st.selectbox("Region", ["All/Not allocated"] + sorted(unique_sub_regions))
133
 
134
  if region_filter == "All/Not allocated":
135
  filtered_country_names = unique_country_names
@@ -140,7 +154,7 @@ else:
140
  ]
141
 
142
  with col2:
143
- country_filter = st.selectbox("Country", ["All/Not allocated"] + filtered_country_names)
144
 
145
  with col3:
146
  current_year = datetime.now().year
@@ -149,33 +163,32 @@ with col3:
149
  "Project End Year",
150
  min_value=2010,
151
  max_value=max_end_year,
152
- value=(default_start_year, max_end_year)
 
153
  )
154
 
155
  with col4:
156
  crs_options = ["All/Not allocated"] + get_crs_options(client, collection_name)
157
- crs_filter = st.selectbox("CRS", crs_options)
158
 
159
  with col5:
160
  min_budget = st.slider(
161
  "Minimum Project Budget (Million €)",
162
  min_value=min_budget_val,
163
  max_value=max_budget_val,
164
- value=min_budget_val
 
165
  )
166
 
167
 
168
-
169
  ###########################################
170
  # Filter Controls - Row 2 (Additional Filters)
171
  ###########################################
172
  col1_2, col2_2, col3_2, col4_2, col5_2 = st.columns(5)
173
 
174
  with col1_2:
175
- # Get unique clients from project_data; adjust column name as needed.
176
  client_options = sorted(project_data["client"].dropna().unique().tolist())
177
- client_filter = st.selectbox("Client", ["All/Not allocated"] + client_options)
178
- # Columns 2-4 reserved (empty)
179
  with col2_2:
180
  st.empty()
181
  with col3_2:
@@ -183,10 +196,11 @@ with col3_2:
183
  with col4_2:
184
  st.empty()
185
  with col5_2:
186
- if st.button("Reset Filters"): # MOD: Reset button in filter row 2, col5
187
- st.experimental_rerun()
188
 
189
  show_exact_matches = st.checkbox("Show only exact matches", value=False)
 
190
  ###########################################
191
  # Main Search / Results
192
  ###########################################
@@ -230,7 +244,7 @@ else:
230
  get_country_name
231
  )
232
 
233
- # Additional filter by client (MOD: added client filter)
234
  if client_filter != "All/Not allocated":
235
  filtered_semantic = [r for r in filtered_semantic if r.payload.get("metadata", {}).get("client", "Unknown Client") == client_filter]
236
  filtered_lexical = [r for r in filtered_lexical if r.payload.get("metadata", {}).get("client", "Unknown Client") == client_filter]
@@ -240,9 +254,6 @@ else:
240
  filtered_lexical_no_dupe = remove_duplicates(filtered_lexical)
241
 
242
  def format_currency(value):
243
- """
244
- Format a numeric or string value as currency (EUR) with commas.
245
- """
246
  try:
247
  return f"€{int(float(value)):,}"
248
  except (ValueError, TypeError):
@@ -250,8 +261,7 @@ else:
250
 
251
  # 3) Display results
252
  if show_exact_matches:
253
- # Lexical substring match only
254
- st.write("Showing **Top Lexical Search results**") # MOD: Removed RAG answer for lexical search
255
  query_substring = var.strip().lower()
256
  lexical_substring_filtered = [
257
  r for r in filtered_lexical
@@ -261,18 +271,15 @@ else:
261
  if not filtered_lexical_no_dupe:
262
  st.write('No exact matches, consider unchecking "Show only exact matches"')
263
  else:
264
- # Use all matching lexical results (or slice as desired)
265
- top_results = filtered_lexical_no_dupe # or use [:15] if you want to limit
266
  for res in top_results:
267
  metadata = res.payload.get('metadata', {})
268
  if "title" not in metadata:
269
  metadata["title"] = compute_title(metadata)
270
- # MOD: Remove hyperlink from title by stripping <a> tags.
271
  title_html = highlight_query(metadata["title"], var) if var.strip() else metadata["title"]
272
  title_clean = re.sub(r'<a.*?>|</a>', '', title_html)
273
  st.markdown(f"#### {title_clean}", unsafe_allow_html=True)
274
 
275
- # Description snippet
276
  objective = metadata.get("objective", "None")
277
  desc_en = metadata.get("description.en", "").strip()
278
  desc_de = metadata.get("description.de", "").strip()
@@ -316,30 +323,28 @@ else:
316
  contact = metadata.get("contact", "").strip()
317
  if contact and contact.lower() != "transparenz@giz.de":
318
  additional_text += f"<br>**Contact:** xxx@giz.de"
319
-
320
  st.markdown(additional_text, unsafe_allow_html=True)
321
 
322
  st.divider()
323
-
324
  else:
325
- # Semantic results
326
  if not filtered_semantic_no_dupe:
327
  st.write("No relevant results found.")
328
  else:
329
- # MOD: Pagination for semantic search results
330
  page_size = 15
331
  total_results = len(filtered_semantic_no_dupe)
332
  total_pages = (total_results - 1) // page_size + 1
333
- if total_pages > 1:
334
- page = st.selectbox("Page", list(range(1, total_pages + 1)))
335
- else:
336
- page = 1
337
- start_index = (page - 1) * page_size
 
 
338
  end_index = start_index + page_size
339
  top_results = filtered_semantic_no_dupe[start_index:end_index]
340
- st.write(f"Showing **{len(top_results)}** Semantic Search results (Page {page} of {total_pages})")
341
-
342
- # MOD: Only display the RAG answer for semantic search and style it distinctively.
343
  rag_answer = get_rag_answer(var, top_results, DEDICATED_ENDPOINT, WRITE_ACCESS_TOKEN)
344
  st.markdown(
345
  f"<div style='background-color: #f0f0f0; color: #333; padding: 10px; border-radius: 5px; font-size:1.2em; text-align:center;'>{rag_answer}</div>",
@@ -351,7 +356,6 @@ else:
351
  metadata = res.payload.get('metadata', {})
352
  if "title" not in metadata:
353
  metadata["title"] = compute_title(metadata)
354
- # MOD: Remove hyperlink from project title
355
  title_clean = re.sub(r'<a.*?>|</a>', '', metadata["title"])
356
  st.markdown(f"#### {title_clean}")
357
 
@@ -398,7 +402,10 @@ else:
398
  contact = metadata.get("contact", "").strip()
399
  if contact and contact.lower() != "transparenz@giz.de":
400
  additional_text += f"<br>**Contact:** xxx@giz.de"
401
-
402
  st.markdown(additional_text, unsafe_allow_html=True)
403
 
404
  st.divider()
 
 
 
 
 
39
  ###########################################
40
  # Model Config
41
  ###########################################
 
42
  config = configparser.ConfigParser()
43
  config.read('model_params.cfg')
44
 
 
122
  )
123
  unique_country_names = sorted(country_name_mapping.keys())
124
 
125
+ ###########################################
126
+ # Define reset_filters function using session_state
127
+ ###########################################
128
+ def reset_filters():
129
+ st.session_state["region_filter"] = "All/Not allocated"
130
+ st.session_state["country_filter"] = "All/Not allocated"
131
+ current_year = datetime.now().year
132
+ default_start_year = current_year - 4
133
+ st.session_state["end_year_range"] = (default_start_year, max_end_year)
134
+ st.session_state["crs_filter"] = "All/Not allocated"
135
+ st.session_state["min_budget"] = min_budget_val
136
+ st.session_state["client_filter"] = "All/Not allocated"
137
+ # Optionally reset page number
138
+ st.session_state["page"] = 1
139
+
140
  ###########################################
141
  # Filter Controls - Row 1
142
  ###########################################
143
  col1, col2, col3, col4, col5 = st.columns([1, 1, 1, 1, 1])
144
 
145
  with col1:
146
+ region_filter = st.selectbox("Region", ["All/Not allocated"] + sorted(unique_sub_regions), key="region_filter")
147
 
148
  if region_filter == "All/Not allocated":
149
  filtered_country_names = unique_country_names
 
154
  ]
155
 
156
  with col2:
157
+ country_filter = st.selectbox("Country", ["All/Not allocated"] + filtered_country_names, key="country_filter")
158
 
159
  with col3:
160
  current_year = datetime.now().year
 
163
  "Project End Year",
164
  min_value=2010,
165
  max_value=max_end_year,
166
+ value=(default_start_year, max_end_year),
167
+ key="end_year_range"
168
  )
169
 
170
  with col4:
171
  crs_options = ["All/Not allocated"] + get_crs_options(client, collection_name)
172
+ crs_filter = st.selectbox("CRS", crs_options, key="crs_filter")
173
 
174
  with col5:
175
  min_budget = st.slider(
176
  "Minimum Project Budget (Million €)",
177
  min_value=min_budget_val,
178
  max_value=max_budget_val,
179
+ value=min_budget_val,
180
+ key="min_budget"
181
  )
182
 
183
 
 
184
  ###########################################
185
  # Filter Controls - Row 2 (Additional Filters)
186
  ###########################################
187
  col1_2, col2_2, col3_2, col4_2, col5_2 = st.columns(5)
188
 
189
  with col1_2:
 
190
  client_options = sorted(project_data["client"].dropna().unique().tolist())
191
+ client_filter = st.selectbox("Client", ["All/Not allocated"] + client_options, key="client_filter")
 
192
  with col2_2:
193
  st.empty()
194
  with col3_2:
 
196
  with col4_2:
197
  st.empty()
198
  with col5_2:
199
+ st.button("Reset Filters", on_click=reset_filters)
200
+
201
 
202
  show_exact_matches = st.checkbox("Show only exact matches", value=False)
203
+
204
  ###########################################
205
  # Main Search / Results
206
  ###########################################
 
244
  get_country_name
245
  )
246
 
247
+ # Additional filter by client
248
  if client_filter != "All/Not allocated":
249
  filtered_semantic = [r for r in filtered_semantic if r.payload.get("metadata", {}).get("client", "Unknown Client") == client_filter]
250
  filtered_lexical = [r for r in filtered_lexical if r.payload.get("metadata", {}).get("client", "Unknown Client") == client_filter]
 
254
  filtered_lexical_no_dupe = remove_duplicates(filtered_lexical)
255
 
256
  def format_currency(value):
 
 
 
257
  try:
258
  return f"€{int(float(value)):,}"
259
  except (ValueError, TypeError):
 
261
 
262
  # 3) Display results
263
  if show_exact_matches:
264
+ st.write("Showing **Top Lexical Search results**")
 
265
  query_substring = var.strip().lower()
266
  lexical_substring_filtered = [
267
  r for r in filtered_lexical
 
271
  if not filtered_lexical_no_dupe:
272
  st.write('No exact matches, consider unchecking "Show only exact matches"')
273
  else:
274
+ top_results = filtered_lexical_no_dupe # Show all matching lexical results
 
275
  for res in top_results:
276
  metadata = res.payload.get('metadata', {})
277
  if "title" not in metadata:
278
  metadata["title"] = compute_title(metadata)
 
279
  title_html = highlight_query(metadata["title"], var) if var.strip() else metadata["title"]
280
  title_clean = re.sub(r'<a.*?>|</a>', '', title_html)
281
  st.markdown(f"#### {title_clean}", unsafe_allow_html=True)
282
 
 
283
  objective = metadata.get("objective", "None")
284
  desc_en = metadata.get("description.en", "").strip()
285
  desc_de = metadata.get("description.de", "").strip()
 
323
  contact = metadata.get("contact", "").strip()
324
  if contact and contact.lower() != "transparenz@giz.de":
325
  additional_text += f"<br>**Contact:** xxx@giz.de"
 
326
  st.markdown(additional_text, unsafe_allow_html=True)
327
 
328
  st.divider()
 
329
  else:
 
330
  if not filtered_semantic_no_dupe:
331
  st.write("No relevant results found.")
332
  else:
 
333
  page_size = 15
334
  total_results = len(filtered_semantic_no_dupe)
335
  total_pages = (total_results - 1) // page_size + 1
336
+
337
+ # Use session_state for page selection; default to 1 if not set.
338
+ if "page" not in st.session_state:
339
+ st.session_state.page = 1
340
+ current_page = st.session_state.page
341
+
342
+ start_index = (current_page - 1) * page_size
343
  end_index = start_index + page_size
344
  top_results = filtered_semantic_no_dupe[start_index:end_index]
345
+
346
+ st.write(f"Showing **{len(top_results)}** Semantic Search results (Page {current_page} of {total_pages})")
347
+
348
  rag_answer = get_rag_answer(var, top_results, DEDICATED_ENDPOINT, WRITE_ACCESS_TOKEN)
349
  st.markdown(
350
  f"<div style='background-color: #f0f0f0; color: #333; padding: 10px; border-radius: 5px; font-size:1.2em; text-align:center;'>{rag_answer}</div>",
 
356
  metadata = res.payload.get('metadata', {})
357
  if "title" not in metadata:
358
  metadata["title"] = compute_title(metadata)
 
359
  title_clean = re.sub(r'<a.*?>|</a>', '', metadata["title"])
360
  st.markdown(f"#### {title_clean}")
361
 
 
402
  contact = metadata.get("contact", "").strip()
403
  if contact and contact.lower() != "transparenz@giz.de":
404
  additional_text += f"<br>**Contact:** xxx@giz.de"
 
405
  st.markdown(additional_text, unsafe_allow_html=True)
406
 
407
  st.divider()
408
+
409
+ # Pagination widget moved to the very end of the page
410
+ new_page = st.selectbox("Select Page", list(range(1, total_pages + 1)), index=current_page - 1, key="page")
411
+ # The selected page value automatically updates st.session_state["page"]