IJ-Reynolds HF Staff commited on
Commit
cf49e11
Β·
verified Β·
1 Parent(s): 05c17b5

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +12 -19
streamlit_app.py CHANGED
@@ -10,11 +10,10 @@ if Path("/data").exists():
10
  else:
11
  CSV_PATH = Path(__file__).resolve().parent / "policy_tracker.csv"
12
 
13
- # --- DATA LOADING (Timezone Safe) ---
14
  def load_data():
15
  if CSV_PATH.exists():
16
  df = pd.read_csv(CSV_PATH, dtype=str)
17
- # Convert and forcefully strip all timezones to prevent crashes
18
  df['event_date'] = pd.to_datetime(df['event_date'], errors='coerce')
19
  if df['event_date'].dt.tz is not None:
20
  df['event_date'] = df['event_date'].dt.tz_localize(None)
@@ -24,15 +23,15 @@ def load_data():
24
  return None
25
 
26
  # --- UI SETUP ---
27
- st.set_page_config(page_title="PolicyPilot Intelligence", layout="wide", page_icon="πŸ›οΈ")
28
- st.title("πŸ›οΈ PolicyPilot Intelligence Dashboard")
29
 
30
  df = load_data()
31
 
32
  # --- SIDEBAR ---
33
  with st.sidebar:
34
  st.header("Controls")
35
- if st.button("πŸš€ Run Live Sweep", use_container_width=True):
36
  with st.spinner("Syncing Gov Schedules, API, Agencies, and Media..."):
37
  importlib.reload(main)
38
  count = main.run()
@@ -43,7 +42,7 @@ with st.sidebar:
43
  st.header("Triage Filters")
44
 
45
  if df is not None and not df.empty:
46
- show_high_only = st.checkbox("🚨 Show HIGH PRIORITY Only", value=False)
47
  available_types = df['type'].dropna().unique().tolist()
48
  selected_types = st.multiselect(
49
  "Filter by Source Type:",
@@ -53,14 +52,14 @@ with st.sidebar:
53
 
54
  # --- EXECUTIVE BRIEFING ---
55
  if df is not None and not df.empty:
56
- st.subheader("πŸ“ Latest Intel Summary")
57
 
58
  if 'executive_summary' not in st.session_state:
59
  st.session_state.executive_summary = "Click the button below to generate a high-level briefing of recent updates."
60
 
61
  st.info(st.session_state.executive_summary)
62
 
63
- if st.button("✨ Generate Executive Briefing"):
64
  with st.spinner("AI is analyzing the latest updates..."):
65
  top_items = df.head(10)
66
  context_text = "\n".join([f"- {row['title']} (Source: {row['source']})" for _, row in top_items.iterrows()])
@@ -87,21 +86,18 @@ def render_event_cards(display_df, is_radar=False):
87
  return
88
 
89
  for _, row in display_df.iterrows():
90
- # Setup the date strings
91
  event_dt = row['event_date']
92
  event_str = event_dt.strftime('%b %d, %Y') if pd.notnull(event_dt) else "Date Unknown"
93
 
94
- # Countdown logic for the Radar tab
95
  countdown_badge = ""
96
  if is_radar and pd.notnull(event_dt):
97
- # Timezone naive now()
98
  days_until = (event_dt.date() - pd.Timestamp.now().tz_localize(None).date()).days
99
  if days_until == 0:
100
- countdown_badge = " [🚨 TODAY]"
101
  elif days_until > 0:
102
- countdown_badge = f" [⏳ In {days_until} days]"
103
 
104
- flag = row.get('triage_flag', 'ℹ️ LOW - MONITOR')
105
 
106
  with st.expander(f"{flag}{countdown_badge} | {event_str} | {row['type']}: {row['source']} | {row['title'][:65]}..."):
107
  col1, col2 = st.columns([3, 1])
@@ -117,18 +113,16 @@ def render_event_cards(display_df, is_radar=False):
117
  st.link_button("Review Original Source", str(row['link']), use_container_width=True)
118
 
119
  if df is not None and not df.empty:
120
- # 1. Apply Filters
121
  filtered_df = df.copy()
122
  if selected_types:
123
  filtered_df = filtered_df[filtered_df['type'].isin(selected_types)]
124
  if show_high_only:
125
  filtered_df = filtered_df[filtered_df['triage_flag'].str.contains("HIGH", na=False)]
126
 
127
- search = st.text_input("πŸ” Search matches...", "")
128
  if search:
129
  filtered_df = filtered_df[filtered_df.apply(lambda r: r.astype(str).str.contains(search, case=False).any(), axis=1)]
130
 
131
- # 2. Timezone-naive date splitting
132
  today = pd.Timestamp.now().tz_localize(None).normalize()
133
 
134
  is_future = filtered_df['event_date'] >= today
@@ -137,8 +131,7 @@ if df is not None and not df.empty:
137
  radar_df = filtered_df[is_future].sort_values(by="event_date", ascending=True)
138
  archive_df = filtered_df[is_past].sort_values(by="event_date", ascending=False)
139
 
140
- # 3. Render Tabs
141
- tab1, tab2 = st.tabs([f"πŸ“‘ Radar (Upcoming: {len(radar_df)})", f"πŸ—„οΈ Archive (Past: {len(archive_df)})"])
142
 
143
  with tab1:
144
  st.subheader("Upcoming Events & Scheduled Action")
 
10
  else:
11
  CSV_PATH = Path(__file__).resolve().parent / "policy_tracker.csv"
12
 
13
+ # --- DATA LOADING ---
14
  def load_data():
15
  if CSV_PATH.exists():
16
  df = pd.read_csv(CSV_PATH, dtype=str)
 
17
  df['event_date'] = pd.to_datetime(df['event_date'], errors='coerce')
18
  if df['event_date'].dt.tz is not None:
19
  df['event_date'] = df['event_date'].dt.tz_localize(None)
 
23
  return None
24
 
25
  # --- UI SETUP ---
26
+ st.set_page_config(page_title="PolicyPilot Intelligence", layout="wide")
27
+ st.title("PolicyPilot Intelligence Dashboard")
28
 
29
  df = load_data()
30
 
31
  # --- SIDEBAR ---
32
  with st.sidebar:
33
  st.header("Controls")
34
+ if st.button("Run Live Sweep", use_container_width=True):
35
  with st.spinner("Syncing Gov Schedules, API, Agencies, and Media..."):
36
  importlib.reload(main)
37
  count = main.run()
 
42
  st.header("Triage Filters")
43
 
44
  if df is not None and not df.empty:
45
+ show_high_only = st.checkbox("Show HIGH PRIORITY Only", value=False)
46
  available_types = df['type'].dropna().unique().tolist()
47
  selected_types = st.multiselect(
48
  "Filter by Source Type:",
 
52
 
53
  # --- EXECUTIVE BRIEFING ---
54
  if df is not None and not df.empty:
55
+ st.subheader("Latest Intel Summary")
56
 
57
  if 'executive_summary' not in st.session_state:
58
  st.session_state.executive_summary = "Click the button below to generate a high-level briefing of recent updates."
59
 
60
  st.info(st.session_state.executive_summary)
61
 
62
+ if st.button("Generate Executive Briefing"):
63
  with st.spinner("AI is analyzing the latest updates..."):
64
  top_items = df.head(10)
65
  context_text = "\n".join([f"- {row['title']} (Source: {row['source']})" for _, row in top_items.iterrows()])
 
86
  return
87
 
88
  for _, row in display_df.iterrows():
 
89
  event_dt = row['event_date']
90
  event_str = event_dt.strftime('%b %d, %Y') if pd.notnull(event_dt) else "Date Unknown"
91
 
 
92
  countdown_badge = ""
93
  if is_radar and pd.notnull(event_dt):
 
94
  days_until = (event_dt.date() - pd.Timestamp.now().tz_localize(None).date()).days
95
  if days_until == 0:
96
+ countdown_badge = " [TODAY]"
97
  elif days_until > 0:
98
+ countdown_badge = f" [In {days_until} days]"
99
 
100
+ flag = row.get('triage_flag', 'LOW - MONITOR')
101
 
102
  with st.expander(f"{flag}{countdown_badge} | {event_str} | {row['type']}: {row['source']} | {row['title'][:65]}..."):
103
  col1, col2 = st.columns([3, 1])
 
113
  st.link_button("Review Original Source", str(row['link']), use_container_width=True)
114
 
115
  if df is not None and not df.empty:
 
116
  filtered_df = df.copy()
117
  if selected_types:
118
  filtered_df = filtered_df[filtered_df['type'].isin(selected_types)]
119
  if show_high_only:
120
  filtered_df = filtered_df[filtered_df['triage_flag'].str.contains("HIGH", na=False)]
121
 
122
+ search = st.text_input("Search matches...", "")
123
  if search:
124
  filtered_df = filtered_df[filtered_df.apply(lambda r: r.astype(str).str.contains(search, case=False).any(), axis=1)]
125
 
 
126
  today = pd.Timestamp.now().tz_localize(None).normalize()
127
 
128
  is_future = filtered_df['event_date'] >= today
 
131
  radar_df = filtered_df[is_future].sort_values(by="event_date", ascending=True)
132
  archive_df = filtered_df[is_past].sort_values(by="event_date", ascending=False)
133
 
134
+ tab1, tab2 = st.tabs([f"Radar (Upcoming: {len(radar_df)})", f"Archive (Past: {len(archive_df)})"])
 
135
 
136
  with tab1:
137
  st.subheader("Upcoming Events & Scheduled Action")