GodsDevProject commited on
Commit
33d032a
·
verified ·
1 Parent(s): f21f499

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -175
app.py CHANGED
@@ -1,45 +1,41 @@
1
  import gradio as gr
2
  import pandas as pd
3
- import plotly.graph_objects as go
4
- import plotly.express as px
5
-
6
- # -----------------------------
7
- # Mock Data (replace with live)
8
- # -----------------------------
9
 
 
 
 
 
 
 
 
 
 
 
 
10
  DATA = pd.DataFrame([
11
  {
12
  "title": "MKULTRA Behavioral Experiments",
13
  "agency": "CIA",
14
  "date": "1977-08-03",
15
  "year": 1977,
16
- "summary": "CIA behavioral research program involving human subjects.",
17
- "entities": ["CIA", "MKULTRA", "Behavioral Research"]
18
  },
19
  {
20
  "title": "Human Performance Research",
21
  "agency": "DoD",
22
  "date": "1975-01-12",
23
  "year": 1975,
24
- "summary": "DoD-funded research on human cognition and stress.",
25
- "entities": ["DoD", "Cognition", "Stress"]
26
- },
27
- {
28
- "title": "Signals Intelligence Overview",
29
- "agency": "NSA",
30
- "date": "1981-04-21",
31
- "year": 1981,
32
- "summary": "Overview of SIGINT collection policies.",
33
- "entities": ["NSA", "SIGINT"]
34
- },
35
  ])
36
 
37
- AGENCIES = ["CIA", "DoD", "DIA", "FBI", "NRO", "NSA", "Unknown"]
38
-
39
- # -----------------------------
40
- # Search Logic
41
- # -----------------------------
42
 
 
 
 
43
  def run_search(query, agencies):
44
  df = DATA.copy()
45
  if query:
@@ -48,75 +44,23 @@ def run_search(query, agencies):
48
  df = df[df["agency"].isin(agencies)]
49
  return df[["title", "agency", "date"]]
50
 
51
- # -----------------------------
52
- # Row Click → Preview
53
- # -----------------------------
54
-
55
  def preview_row(evt: gr.SelectData):
56
  row = DATA.iloc[evt.index]
57
  return f"""
58
  ### {row['title']}
59
-
60
  **Agency:** {row['agency']}
61
  **Date:** {row['date']}
62
 
63
  {row['summary']}
64
  """
65
 
66
- # -----------------------------
67
- # Entity Graph (Plotly)
68
- # -----------------------------
69
-
70
- def entity_graph(filtered_df):
71
- nodes = set()
72
- edges = []
73
-
74
- for _, row in filtered_df.iterrows():
75
- for e in row["entities"]:
76
- nodes.add(e)
77
- edges.append((row["agency"], e))
78
-
79
- nodes = list(nodes)
80
- node_index = {n: i for i, n in enumerate(nodes)}
81
-
82
- x = list(range(len(nodes)))
83
- y = [0] * len(nodes)
84
-
85
- edge_x, edge_y = [], []
86
- for a, b in edges:
87
- if b in node_index:
88
- edge_x += [node_index.get(a, 0), node_index[b], None]
89
- edge_y += [0, 0, None]
90
-
91
- fig = go.Figure()
92
- fig.add_trace(go.Scatter(
93
- x=edge_x, y=edge_y,
94
- mode="lines",
95
- line=dict(color="#334155"),
96
- hoverinfo="none"
97
- ))
98
- fig.add_trace(go.Scatter(
99
- x=x, y=y,
100
- mode="markers+text",
101
- marker=dict(size=18, color="#2563eb"),
102
- text=nodes,
103
- textposition="bottom center"
104
- ))
105
-
106
- fig.update_layout(
107
- paper_bgcolor="#020617",
108
- plot_bgcolor="#020617",
109
- font_color="#e5e7eb",
110
- margin=dict(l=20, r=20, t=20, b=20),
111
- height=400
112
- )
113
- return fig
114
-
115
- # -----------------------------
116
- # Coverage Heatmap
117
- # -----------------------------
118
-
119
  def coverage_heatmap():
 
 
 
120
  heat = DATA.groupby(["agency", "year"]).size().reset_index(name="count")
121
  fig = px.density_heatmap(
122
  heat,
@@ -125,107 +69,53 @@ def coverage_heatmap():
125
  z="count",
126
  color_continuous_scale="Blues"
127
  )
128
- fig.update_layout(
129
- paper_bgcolor="#020617",
130
- plot_bgcolor="#020617",
131
- font_color="#e5e7eb",
132
- height=300
133
- )
134
  return fig
135
 
136
- # -----------------------------
137
- # Timeline View
138
- # -----------------------------
139
-
140
- def timeline_view(filtered_df):
141
- fig = px.scatter(
142
- filtered_df,
143
- x="year",
144
- y="agency",
145
- hover_name="title"
146
- )
147
- fig.update_traces(marker=dict(size=14, color="#38bdf8"))
148
- fig.update_layout(
149
- paper_bgcolor="#020617",
150
- plot_bgcolor="#020617",
151
- font_color="#e5e7eb",
152
- height=300
153
  )
 
154
  return fig
155
 
156
- # -----------------------------
157
  # UI
158
- # -----------------------------
159
-
160
- with gr.Blocks(
161
- title="Federal FOIA Intelligence Search",
162
- css="static/style.css"
163
- ) as demo:
164
-
165
- gr.Markdown("# 🏛️ Federal FOIA Intelligence Search\n**Public Electronic Reading Rooms Only**")
166
-
167
- with gr.Tabs():
168
- with gr.Tab("🔍 Search"):
169
- with gr.Row():
170
- with gr.Column(scale=2):
171
- with gr.Column(elem_id="card"):
172
- query = gr.Textbox(label="Search query", placeholder="MKULTRA")
173
- agencies = gr.CheckboxGroup(
174
- AGENCIES,
175
- value=["CIA", "DoD", "NRO"],
176
- label="Filter by agency",
177
- elem_id="agency-pills"
178
- )
179
- search_btn = gr.Button("Search", elem_id="search-btn")
180
-
181
- results = gr.Dataframe(
182
- headers=["Title", "Agency", "Date"],
183
- interactive=False,
184
- elem_id="results-table"
185
- )
186
-
187
- with gr.Column(scale=1):
188
- preview = gr.Markdown("### Document Preview\nSelect a result")
189
-
190
- search_btn.click(
191
- run_search,
192
- inputs=[query, agencies],
193
- outputs=results
194
- )
195
-
196
- results.select(preview_row, outputs=preview)
197
-
198
- with gr.Tab("🧠 Entity Graph"):
199
- entity_plot = gr.Plot()
200
-
201
- with gr.Tab("📊 Coverage"):
202
- heatmap_plot = gr.Plot()
203
-
204
- with gr.Tab("⏱ Timeline"):
205
- timeline_plot = gr.Plot()
206
-
207
- # Reactive wiring
208
- results.change(
209
- lambda df: entity_graph(DATA),
210
- inputs=results,
211
- outputs=entity_plot
212
- )
213
 
214
- results.change(
215
- lambda df: timeline_view(DATA),
216
- inputs=results,
217
- outputs=timeline_plot
218
- )
219
 
220
- heatmap_plot.render(coverage_heatmap)
 
221
 
222
- with gr.Column(elem_id="provenance"):
223
- gr.Markdown("""
224
- ### Dataset Provenance
225
- - **Sources:** Public FOIA Reading Rooms (CIA, DoD, NSA)
226
- - **Status:** Previously released, unclassified
227
- - **Scope:** Demonstration subset
228
- - **Verification:** No inference beyond document text
229
- """)
 
 
 
 
 
 
 
 
230
 
231
  demo.launch()
 
1
  import gradio as gr
2
  import pandas as pd
 
 
 
 
 
 
3
 
4
+ # Optional Plotly
5
+ try:
6
+ import plotly.express as px
7
+ import plotly.graph_objects as go
8
+ PLOTLY = True
9
+ except Exception:
10
+ PLOTLY = False
11
+
12
+ # ---------------------------
13
+ # Demo FOIA Data
14
+ # ---------------------------
15
  DATA = pd.DataFrame([
16
  {
17
  "title": "MKULTRA Behavioral Experiments",
18
  "agency": "CIA",
19
  "date": "1977-08-03",
20
  "year": 1977,
21
+ "summary": "CIA behavioral research involving human subjects.",
22
+ "entities": ["CIA", "MKULTRA"]
23
  },
24
  {
25
  "title": "Human Performance Research",
26
  "agency": "DoD",
27
  "date": "1975-01-12",
28
  "year": 1975,
29
+ "summary": "DoD-funded cognition research.",
30
+ "entities": ["DoD", "Cognition"]
31
+ }
 
 
 
 
 
 
 
 
32
  ])
33
 
34
+ AGENCIES = sorted(DATA["agency"].unique().tolist())
 
 
 
 
35
 
36
+ # ---------------------------
37
+ # Search
38
+ # ---------------------------
39
  def run_search(query, agencies):
40
  df = DATA.copy()
41
  if query:
 
44
  df = df[df["agency"].isin(agencies)]
45
  return df[["title", "agency", "date"]]
46
 
 
 
 
 
47
  def preview_row(evt: gr.SelectData):
48
  row = DATA.iloc[evt.index]
49
  return f"""
50
  ### {row['title']}
 
51
  **Agency:** {row['agency']}
52
  **Date:** {row['date']}
53
 
54
  {row['summary']}
55
  """
56
 
57
+ # ---------------------------
58
+ # Visuals
59
+ # ---------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  def coverage_heatmap():
61
+ if not PLOTLY:
62
+ return None
63
+
64
  heat = DATA.groupby(["agency", "year"]).size().reset_index(name="count")
65
  fig = px.density_heatmap(
66
  heat,
 
69
  z="count",
70
  color_continuous_scale="Blues"
71
  )
72
+ fig.update_layout(height=300)
 
 
 
 
 
73
  return fig
74
 
75
+ def entity_graph():
76
+ if not PLOTLY:
77
+ return None
78
+
79
+ nodes = list(set(sum(DATA["entities"].tolist(), [])))
80
+ fig = go.Figure(
81
+ data=go.Scatter(
82
+ x=list(range(len(nodes))),
83
+ y=[0]*len(nodes),
84
+ mode="markers+text",
85
+ text=nodes
86
+ )
 
 
 
 
 
87
  )
88
+ fig.update_layout(height=300)
89
  return fig
90
 
91
+ # ---------------------------
92
  # UI
93
+ # ---------------------------
94
+ with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
+ gr.Markdown("""
97
+ # 🏛️ Federal FOIA Intelligence Search
98
+ **Public Electronic Reading Rooms Only**
99
+ """)
 
100
 
101
+ if not PLOTLY:
102
+ gr.Markdown("⚠️ Plotly not installed — graphs disabled.")
103
 
104
+ with gr.Tab("🔍 Search"):
105
+ query = gr.Textbox(label="Search query", value="MKULTRA")
106
+ agencies = gr.CheckboxGroup(AGENCIES, value=AGENCIES)
107
+ search_btn = gr.Button("Search")
108
+
109
+ table = gr.Dataframe(headers=["Title", "Agency", "Date"])
110
+ preview = gr.Markdown()
111
+
112
+ search_btn.click(run_search, [query, agencies], table)
113
+ table.select(preview_row, preview)
114
+
115
+ with gr.Tab("📊 Coverage Heatmap"):
116
+ gr.Plot(value=coverage_heatmap)
117
+
118
+ with gr.Tab("🧠 Entity Graph"):
119
+ gr.Plot(value=entity_graph)
120
 
121
  demo.launch()