IJ-Reynolds HF Staff commited on
Commit
cca9db9
·
verified ·
1 Parent(s): c9c137f

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +49 -6
streamlit_app.py CHANGED
@@ -5,7 +5,7 @@ import main
5
  from pathlib import Path
6
  from datetime import datetime
7
 
8
- # --- PATHING ---
9
  if Path("/data").exists():
10
  CSV_PATH = Path("/data/policy_tracker.csv")
11
  else:
@@ -24,6 +24,33 @@ def load_data():
24
  return df.sort_values(by="event_date", ascending=False)
25
  return None
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  # --- UI SETUP ---
28
  st.set_page_config(page_title="PolicyPilot Intel", layout="wide")
29
  st.title("PolicyPilot Intelligence Dashboard")
@@ -45,12 +72,25 @@ with st.sidebar:
45
 
46
  if df is not None and not df.empty:
47
  # Dynamically pull every unique category type found in the CSV
48
- available_types = df['type'].unique().tolist()
49
  selected_types = st.multiselect(
50
  "Filter by Category:",
51
  options=available_types,
52
  default=available_types
53
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  # --- EXECUTIVE BRIEFING ---
56
  if df is not None and not df.empty:
@@ -63,8 +103,9 @@ if df is not None and not df.empty:
63
 
64
  if st.button("Generate Briefing"):
65
  with st.spinner("AI is synthesizing latest data..."):
66
- # Pull top 10 items for context
67
- top_items = df.head(10)
 
68
  context_text = "\n".join([f"- {row['title']} (Source: {row['source']})" for _, row in top_items.iterrows()])
69
 
70
  summary_prompt = f"Provide a 3-bullet point executive summary highlighting the most critical shifts in these updates for a policy team. Use professional language:\n\n{context_text}"
@@ -132,8 +173,10 @@ def render_event_cards(display_df, is_radar=False):
132
 
133
  # --- TAB LOGIC ---
134
  if df is not None and not df.empty:
135
- # Filter by selected types
136
- filtered_df = df.copy()
 
 
137
  if selected_types:
138
  filtered_df = filtered_df[filtered_df['type'].isin(selected_types)]
139
 
 
5
  from pathlib import Path
6
  from datetime import datetime
7
 
8
+ # --- PATHING LOGIC ---
9
  if Path("/data").exists():
10
  CSV_PATH = Path("/data/policy_tracker.csv")
11
  else:
 
24
  return df.sort_values(by="event_date", ascending=False)
25
  return None
26
 
27
+ # --- RETENTION POLICY (UI CLEANER) ---
28
+ def apply_retention_policy(df):
29
+ if df.empty:
30
+ return df
31
+
32
+ today = pd.Timestamp.now().tz_localize(None).normalize()
33
+
34
+ # 1. Legislation: Keep everything (No expiration)
35
+ leg_df = df[df['type'] == 'Legislation']
36
+
37
+ # 2. News/Media & Exec Action: Keep last 30 days (and any future anomalies)
38
+ news_types = ['News/Media', 'Federal/Exec Action']
39
+ news_mask = (df['type'].isin(news_types)) & ((df['event_date'] >= today - pd.Timedelta(days=30)) | df['event_date'].isna())
40
+ news_df = df[news_mask]
41
+
42
+ # 3. Schedules: Keep last 60 days (and all future scheduled events)
43
+ sched_types = ['Schedule/Hearing', 'Hearing/Markup']
44
+ sched_mask = (df['type'].isin(sched_types)) & ((df['event_date'] >= today - pd.Timedelta(days=60)) | df['event_date'].isna())
45
+ sched_df = df[sched_mask]
46
+
47
+ # 4. Fallback for any undefined types
48
+ other_df = df[~df['type'].isin(['Legislation'] + news_types + sched_types)]
49
+
50
+ # Combine the filtered datasets
51
+ active_df = pd.concat([leg_df, news_df, sched_df, other_df]).drop_duplicates(subset=['link'])
52
+ return active_df.sort_values(by="event_date", ascending=False)
53
+
54
  # --- UI SETUP ---
55
  st.set_page_config(page_title="PolicyPilot Intel", layout="wide")
56
  st.title("PolicyPilot Intelligence Dashboard")
 
72
 
73
  if df is not None and not df.empty:
74
  # Dynamically pull every unique category type found in the CSV
75
+ available_types = df['type'].dropna().unique().tolist()
76
  selected_types = st.multiselect(
77
  "Filter by Category:",
78
  options=available_types,
79
  default=available_types
80
  )
81
+
82
+ st.divider()
83
+ st.header("Data Management")
84
+ if df is not None and not df.empty:
85
+ # Convert the raw, unfiltered dataframe to CSV for download
86
+ csv_data = df.to_csv(index=False).encode('utf-8')
87
+ st.download_button(
88
+ label="Download Full Historical Archive (CSV)",
89
+ data=csv_data,
90
+ file_name=f"policy_pilot_archive_{pd.Timestamp.now().strftime('%Y-%m-%d')}.csv",
91
+ mime="text/csv",
92
+ use_container_width=True
93
+ )
94
 
95
  # --- EXECUTIVE BRIEFING ---
96
  if df is not None and not df.empty:
 
103
 
104
  if st.button("Generate Briefing"):
105
  with st.spinner("AI is synthesizing latest data..."):
106
+ # Pull top 10 items from the filtered active view for context
107
+ active_data = apply_retention_policy(df.copy())
108
+ top_items = active_data.head(10)
109
  context_text = "\n".join([f"- {row['title']} (Source: {row['source']})" for _, row in top_items.iterrows()])
110
 
111
  summary_prompt = f"Provide a 3-bullet point executive summary highlighting the most critical shifts in these updates for a policy team. Use professional language:\n\n{context_text}"
 
173
 
174
  # --- TAB LOGIC ---
175
  if df is not None and not df.empty:
176
+ # Apply our tiered retention rules to clean up the UI
177
+ filtered_df = apply_retention_policy(df.copy())
178
+
179
+ # Filter by selected types from the sidebar
180
  if selected_types:
181
  filtered_df = filtered_df[filtered_df['type'].isin(selected_types)]
182