GodsDevProject commited on
Commit
8d11cfe
·
verified ·
1 Parent(s): 113424c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -18
app.py CHANGED
@@ -12,7 +12,7 @@ from analytics import log_event
12
 
13
 
14
  # ============================================================
15
- # Configuration
16
  # ============================================================
17
 
18
  APP_TITLE = "Federal FOIA Intelligence Search"
@@ -23,46 +23,68 @@ ALL_ADAPTERS = get_all_adapters()
23
 
24
 
25
  # ============================================================
26
- # Adapter Selection Logic
27
  # ============================================================
28
 
29
- def get_active_adapters(
30
- include_stubs: bool,
31
- enable_extended: bool
32
- ) -> Dict[str, object]:
33
- """
34
- Filter adapters based on UI toggles and safety policy.
35
- """
36
  active = {}
37
 
38
  for name, adapter in ALL_ADAPTERS.items():
39
  if kill_switch.is_disabled(name):
40
  continue
41
-
42
  if getattr(adapter, "is_stub", False) and not include_stubs:
43
  continue
44
-
45
  if getattr(adapter, "extended", False) and not enable_extended:
46
  continue
47
-
48
  active[name] = adapter
49
 
50
  return active
51
 
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  # ============================================================
54
- # Async Federated Search
55
  # ============================================================
56
 
57
  async def federated_search(query: str, adapters: Dict[str, object]) -> List[dict]:
58
  tasks = [adapter.search(query) for adapter in adapters.values()]
59
  results = await asyncio.gather(*tasks, return_exceptions=True)
60
 
61
- flattened: List[dict] = []
62
- for result in results:
63
- if isinstance(result, Exception):
64
  continue
65
- flattened.extend(result)
66
 
67
  return flattened
68
 
@@ -75,6 +97,9 @@ def search_handler(query, include_stubs, enable_extended):
75
 
76
  adapters = get_active_adapters(include_stubs, enable_extended)
77
 
 
 
 
78
  try:
79
  results = asyncio.run(federated_search(query, adapters))
80
  except RuntimeError:
@@ -90,7 +115,7 @@ def search_handler(query, include_stubs, enable_extended):
90
 
91
 
92
  # ============================================================
93
- # Gradio UI
94
  # ============================================================
95
 
96
  with gr.Blocks(title=APP_TITLE) as demo:
@@ -143,6 +168,45 @@ Electronic Reading Rooms**.
143
  outputs=[results, status]
144
  )
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  gr.Markdown(
147
  """
148
  ---
 
12
 
13
 
14
  # ============================================================
15
+ # App Metadata
16
  # ============================================================
17
 
18
  APP_TITLE = "Federal FOIA Intelligence Search"
 
23
 
24
 
25
  # ============================================================
26
+ # Adapter Utilities
27
  # ============================================================
28
 
29
+ def get_active_adapters(include_stubs: bool, enable_extended: bool) -> Dict[str, object]:
 
 
 
 
 
 
30
  active = {}
31
 
32
  for name, adapter in ALL_ADAPTERS.items():
33
  if kill_switch.is_disabled(name):
34
  continue
 
35
  if getattr(adapter, "is_stub", False) and not include_stubs:
36
  continue
 
37
  if getattr(adapter, "extended", False) and not enable_extended:
38
  continue
 
39
  active[name] = adapter
40
 
41
  return active
42
 
43
 
44
+ def build_coverage_heatmap(include_stubs: bool, enable_extended: bool):
45
+ """
46
+ Returns a table describing agency coverage state.
47
+ """
48
+ rows = []
49
+
50
+ for name, adapter in ALL_ADAPTERS.items():
51
+ if kill_switch.is_disabled(name):
52
+ status = "🔴 Disabled"
53
+ elif getattr(adapter, "is_stub", False):
54
+ status = "🟡 Stub"
55
+ else:
56
+ status = "🟢 Live"
57
+
58
+ scope = "Extended" if getattr(adapter, "extended", False) else "Default"
59
+
60
+ if scope == "Extended" and not enable_extended:
61
+ status = "⚪ Hidden (Extended Disabled)"
62
+
63
+ if getattr(adapter, "is_stub", False) and not include_stubs:
64
+ status = "⚪ Hidden (Stubs Disabled)"
65
+
66
+ rows.append([
67
+ name,
68
+ scope,
69
+ status
70
+ ])
71
+
72
+ return rows
73
+
74
+
75
  # ============================================================
76
+ # Async Search
77
  # ============================================================
78
 
79
  async def federated_search(query: str, adapters: Dict[str, object]) -> List[dict]:
80
  tasks = [adapter.search(query) for adapter in adapters.values()]
81
  results = await asyncio.gather(*tasks, return_exceptions=True)
82
 
83
+ flattened = []
84
+ for r in results:
85
+ if isinstance(r, Exception):
86
  continue
87
+ flattened.extend(r)
88
 
89
  return flattened
90
 
 
97
 
98
  adapters = get_active_adapters(include_stubs, enable_extended)
99
 
100
+ if not adapters:
101
+ return [], "⚠️ No active sources enabled."
102
+
103
  try:
104
  results = asyncio.run(federated_search(query, adapters))
105
  except RuntimeError:
 
115
 
116
 
117
  # ============================================================
118
+ # UI
119
  # ============================================================
120
 
121
  with gr.Blocks(title=APP_TITLE) as demo:
 
168
  outputs=[results, status]
169
  )
170
 
171
+ # ========================================================
172
+ # Coverage Heatmap Panel
173
+ # ========================================================
174
+
175
+ with gr.Accordion("🗺️ Agency Coverage Map", open=False):
176
+ gr.Markdown(
177
+ """
178
+ This panel shows **search coverage status** by agency.
179
+
180
+ - 🟢 Live = searchable public FOIA reading room
181
+ - 🟡 Stub = declared coverage (not yet live)
182
+ - 🔴 Disabled = kill switch / unavailable
183
+ """
184
+ )
185
+
186
+ coverage_table = gr.Dataframe(
187
+ headers=["Agency", "Scope", "Coverage Status"],
188
+ datatype=["str", "str", "str"],
189
+ interactive=False
190
+ )
191
+
192
+ def refresh_coverage(include_stubs, enable_extended):
193
+ return build_coverage_heatmap(include_stubs, enable_extended)
194
+
195
+ include_stubs.change(
196
+ refresh_coverage,
197
+ inputs=[include_stubs, enable_extended],
198
+ outputs=[coverage_table]
199
+ )
200
+
201
+ enable_extended.change(
202
+ refresh_coverage,
203
+ inputs=[include_stubs, enable_extended],
204
+ outputs=[coverage_table]
205
+ )
206
+
207
+ # Initial render
208
+ coverage_table.value = build_coverage_heatmap(True, False)
209
+
210
  gr.Markdown(
211
  """
212
  ---