cjc0013 commited on
Commit
a7d08d8
·
verified ·
1 Parent(s): d506fc7

Update private self-contained Congress Space bundle

Browse files
README.md CHANGED
@@ -1,31 +1,30 @@
1
- ---
2
- title: Congress Public Records Slice
3
- emoji: 🔎
4
- colorFrom: green
5
- colorTo: yellow
6
- sdk: gradio
7
- sdk_version: "5.23.1"
8
- python_version: "3.11"
9
- app_file: app.py
10
- pinned: false
11
- ---
12
-
13
-
14
- # Congress Public Records Slice Space
15
-
16
- Neutral Records explorer for a public-record slice of congressional money-and-power linkages.
17
-
18
- ## Runtime Notes
19
-
20
- - This Space first checks for a bundled local `dataset_bundle` inside the Space repo, then falls back to the configured Hugging Face dataset repo.
21
- - For local testing, set the `PUBLIC_RELEASE_LOCAL_ROOT` environment variable to the release root folder before launching `app.py`.
22
- - The Space is intentionally neutral and does not assign guilt, wrongdoing, intent, or causality.
23
-
24
- ## Required Caveats
25
-
26
- - This release is a slice of public-record data, not a complete accounting of all potentially relevant data.
27
- - Future releases may update or expand this slice as source recovery, parsing, and evidence linkage improve.
28
- - This release does not assign guilt, wrongdoing, intent, or causality to any person or organization.
29
- - The release shows public-record overlaps, timing, and linkage strength, not proof of illegality or corruption.
30
- - Some rows remain review-tier or include unresolved official source references and should be read with those labels in mind.
31
  - The public package includes verification summaries and SHA-backed artifact indexes, but it does not include the full internal raw corpus, so external verification is bounded by what is published here.
 
1
+ ---
2
+ title: Congress Public Records Slice
3
+ emoji: 🔎
4
+ colorFrom: green
5
+ colorTo: yellow
6
+ sdk: gradio
7
+ sdk_version: "5.23.1"
8
+ python_version: "3.11"
9
+ app_file: app.py
10
+ pinned: false
11
+ ---
12
+
13
+ # Congress Public Records Slice Space
14
+
15
+ Neutral Records explorer for a public-record slice of congressional money-and-power linkages.
16
+
17
+ ## Runtime Notes
18
+
19
+ - This Space first checks for a bundled local `dataset_bundle` inside the Space repo, then falls back to the configured Hugging Face dataset repo.
20
+ - For local testing, set the `PUBLIC_RELEASE_LOCAL_ROOT` environment variable to the release root folder before launching `app.py`.
21
+ - The Space is intentionally neutral and does not assign guilt, wrongdoing, intent, or causality.
22
+
23
+ ## Required Caveats
24
+
25
+ - This release is a slice of public-record data, not a complete accounting of all potentially relevant data.
26
+ - Future releases may update or expand this slice as source recovery, parsing, and evidence linkage improve.
27
+ - This release does not assign guilt, wrongdoing, intent, or causality to any person or organization.
28
+ - The release shows public-record overlaps, timing, and linkage strength, not proof of illegality or corruption.
29
+ - Some rows remain review-tier or include unresolved official source references and should be read with those labels in mind.
 
30
  - The public package includes verification summaries and SHA-backed artifact indexes, but it does not include the full internal raw corpus, so external verification is bounded by what is published here.
__pycache__/public_space_app.cpython-311.pyc ADDED
Binary file (48.3 kB). View file
 
public_copy.json CHANGED
@@ -4,6 +4,7 @@
4
  "subtitle": "Neutral Records explorer for a public-record slice of congressional money-and-power linkages.",
5
  "dataset_repo_id": "cjc0013/cmp-data",
6
  "space_repo_id": "cjc0013/cmp",
 
7
  "landing_markdown": "# Congress Public Records Slice\n\nA neutral, review-oriented slice of House public-record linkages across financial disclosures, sector overlap, and community project funding recipient relationships.\n\n- This release is a slice of public-record data, not a complete accounting of all potentially relevant data.\n- Future releases may update or expand this slice as source recovery, parsing, and evidence linkage improve.\n- This release does not assign guilt, wrongdoing, intent, or causality to any person or organization.\n- The release shows public-record overlaps, timing, and linkage strength, not proof of illegality or corruption.\n- Some rows remain review-tier or include unresolved official source references and should be read with those labels in mind.\n- The public package includes verification summaries and SHA-backed artifact indexes, but it does not include the full internal raw corpus, so external verification is bounded by what is published here.",
8
  "downloads_markdown": "## Downloads\n\n- Dataset repo id: `cjc0013/cmp-data`\n- Space repo id: `cjc0013/cmp`\n\nUse the dataset bundle files for direct review, CSV download, and SHA-backed source checks.",
9
  "dataset_bundle_prefix": "dataset_bundle"
 
4
  "subtitle": "Neutral Records explorer for a public-record slice of congressional money-and-power linkages.",
5
  "dataset_repo_id": "cjc0013/cmp-data",
6
  "space_repo_id": "cjc0013/cmp",
7
+ "welcome_markdown": "# Congress Public Records Slice\n\nStart with the **Network Graph** tab.\n\n- Search one House member name first.\n- Green dots are House members, rust dots are funding recipients, and gold dots are sectors.\n- Lines show public-record support in this released slice; thicker lines mean more supporting rows.\n- Use **Explore** and **Event Detail** to inspect the underlying rows, source URLs, and SHA-backed artifacts.\n\nThis is an exploration tool, not an accusation tool.",
8
  "landing_markdown": "# Congress Public Records Slice\n\nA neutral, review-oriented slice of House public-record linkages across financial disclosures, sector overlap, and community project funding recipient relationships.\n\n- This release is a slice of public-record data, not a complete accounting of all potentially relevant data.\n- Future releases may update or expand this slice as source recovery, parsing, and evidence linkage improve.\n- This release does not assign guilt, wrongdoing, intent, or causality to any person or organization.\n- The release shows public-record overlaps, timing, and linkage strength, not proof of illegality or corruption.\n- Some rows remain review-tier or include unresolved official source references and should be read with those labels in mind.\n- The public package includes verification summaries and SHA-backed artifact indexes, but it does not include the full internal raw corpus, so external verification is bounded by what is published here.",
9
  "downloads_markdown": "## Downloads\n\n- Dataset repo id: `cjc0013/cmp-data`\n- Space repo id: `cjc0013/cmp`\n\nUse the dataset bundle files for direct review, CSV download, and SHA-backed source checks.",
10
  "dataset_bundle_prefix": "dataset_bundle"
public_space_app.py CHANGED
@@ -245,6 +245,18 @@ def _consistency_summary_markdown(consistency: Dict[str, Any]) -> str:
245
  )
246
 
247
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  def _render_graph(nodes: pd.DataFrame, edges: pd.DataFrame) -> str:
249
  if edges.empty:
250
  return "<div style=\"padding: 1rem; border: 1px solid #d6d0c4; background: #fffdf8; color: #3a3a3a;\">No relationships match the current filters.</div>"
@@ -332,7 +344,7 @@ def _render_graph(nodes: pd.DataFrame, edges: pd.DataFrame) -> str:
332
  color=edge_style["color"],
333
  dashes=edge_style["dashes"],
334
  )
335
- return network.generate_html(notebook=False)
336
 
337
 
338
  def _event_detail(events: pd.DataFrame, provenance: pd.DataFrame, event_id: str) -> Tuple[str, pd.DataFrame]:
@@ -421,18 +433,7 @@ def build_app(copy_path: str | Path):
421
  overview_member_limit = int(graph_defaults.get("overview_member_limit", 8))
422
 
423
  with gr.Blocks(title=copy_payload.get("title", "Congress Public Records Slice")) as app:
424
- gr.Markdown(copy_payload.get("landing_markdown", ""))
425
- with gr.Tab("Explore"):
426
- with gr.Row():
427
- member_query = gr.Textbox(label="Member name or slug")
428
- event_type = gr.Dropdown(label="Event type", choices=event_type_choices, value="all")
429
- score_label = gr.Dropdown(label="Score label", choices=score_label_choices, value="all")
430
- text_query = gr.Textbox(label="Issuer or sector search")
431
- explore_df = gr.Dataframe(value=events.head(100), interactive=False)
432
- def _update_events(member_query: str, event_type: str, score_label: str, text_query: str):
433
- return _filter_events(events, member_query, event_type, score_label, text_query)
434
- for control in (member_query, event_type, score_label, text_query):
435
- control.change(_update_events, [member_query, event_type, score_label, text_query], explore_df)
436
  with gr.Tab("Network Graph"):
437
  gr.Markdown(_graph_intro_markdown(data["graph_config"]))
438
  with gr.Row():
@@ -453,6 +454,17 @@ def build_app(copy_path: str | Path):
453
  for control in (family, member_graph_query, target_query, graph_score, review_status, hide_unresolved_only, max_edges):
454
  control.change(_update_graph, [family, member_graph_query, target_query, graph_score, review_status, hide_unresolved_only, max_edges], [graph_html, graph_df])
455
  app.load(_update_graph, [family, member_graph_query, target_query, graph_score, review_status, hide_unresolved_only, max_edges], [graph_html, graph_df])
 
 
 
 
 
 
 
 
 
 
 
456
  with gr.Tab("Event Detail"):
457
  event_id = gr.Dropdown(label="Event id", choices=event_id_choices, value=event_id_choices[0] if event_id_choices else None)
458
  event_detail_md = gr.Markdown()
 
245
  )
246
 
247
 
248
+ def _embed_html_document(document_html: str, *, height: int = 760) -> str:
249
+ escaped = html.escape(document_html, quote=True)
250
+ return (
251
+ "<div style=\"border: 1px solid #d6d0c4; border-radius: 12px; overflow: hidden; background: #fbf7ee;\">"
252
+ f"<iframe srcdoc=\"{escaped}\" "
253
+ "style=\"width: 100%; border: 0; background: #fbf7ee;\" "
254
+ f"height=\"{int(height)}\" "
255
+ "sandbox=\"allow-scripts allow-same-origin allow-popups allow-downloads\"></iframe>"
256
+ "</div>"
257
+ )
258
+
259
+
260
  def _render_graph(nodes: pd.DataFrame, edges: pd.DataFrame) -> str:
261
  if edges.empty:
262
  return "<div style=\"padding: 1rem; border: 1px solid #d6d0c4; background: #fffdf8; color: #3a3a3a;\">No relationships match the current filters.</div>"
 
344
  color=edge_style["color"],
345
  dashes=edge_style["dashes"],
346
  )
347
+ return _embed_html_document(network.generate_html(notebook=False))
348
 
349
 
350
  def _event_detail(events: pd.DataFrame, provenance: pd.DataFrame, event_id: str) -> Tuple[str, pd.DataFrame]:
 
433
  overview_member_limit = int(graph_defaults.get("overview_member_limit", 8))
434
 
435
  with gr.Blocks(title=copy_payload.get("title", "Congress Public Records Slice")) as app:
436
+ gr.Markdown(copy_payload.get("welcome_markdown", copy_payload.get("landing_markdown", "")))
 
 
 
 
 
 
 
 
 
 
 
437
  with gr.Tab("Network Graph"):
438
  gr.Markdown(_graph_intro_markdown(data["graph_config"]))
439
  with gr.Row():
 
454
  for control in (family, member_graph_query, target_query, graph_score, review_status, hide_unresolved_only, max_edges):
455
  control.change(_update_graph, [family, member_graph_query, target_query, graph_score, review_status, hide_unresolved_only, max_edges], [graph_html, graph_df])
456
  app.load(_update_graph, [family, member_graph_query, target_query, graph_score, review_status, hide_unresolved_only, max_edges], [graph_html, graph_df])
457
+ with gr.Tab("Explore"):
458
+ with gr.Row():
459
+ member_query = gr.Textbox(label="Member name or slug")
460
+ event_type = gr.Dropdown(label="Event type", choices=event_type_choices, value="all")
461
+ score_label = gr.Dropdown(label="Score label", choices=score_label_choices, value="all")
462
+ text_query = gr.Textbox(label="Issuer or sector search")
463
+ explore_df = gr.Dataframe(value=events.head(100), interactive=False)
464
+ def _update_events(member_query: str, event_type: str, score_label: str, text_query: str):
465
+ return _filter_events(events, member_query, event_type, score_label, text_query)
466
+ for control in (member_query, event_type, score_label, text_query):
467
+ control.change(_update_events, [member_query, event_type, score_label, text_query], explore_df)
468
  with gr.Tab("Event Detail"):
469
  event_id = gr.Dropdown(label="Event id", choices=event_id_choices, value=event_id_choices[0] if event_id_choices else None)
470
  event_detail_md = gr.Markdown()
requirements.txt CHANGED
@@ -1,3 +1,2 @@
1
- pandas>=2.2.0
2
- pyvis>=0.3.2
3
-
 
1
+ pandas>=2.2.0
2
+ pyvis>=0.3.2