Spaces:
Sleeping
Sleeping
Update streamlit_app.py
Browse files- streamlit_app.py +15 -35
streamlit_app.py
CHANGED
|
@@ -66,29 +66,6 @@ def load_daily_summary() -> dict:
|
|
| 66 |
|
| 67 |
|
| 68 |
def normalize_summary_payload(summary: dict) -> dict:
|
| 69 |
-
"""
|
| 70 |
-
Supports both the improved API shape and the previous legacy shape.
|
| 71 |
-
|
| 72 |
-
Preferred shape:
|
| 73 |
-
{
|
| 74 |
-
"summary_date": "...",
|
| 75 |
-
"generated_at": "...",
|
| 76 |
-
"executive_summary": "...",
|
| 77 |
-
"key_signal": "...",
|
| 78 |
-
"recommended_focus": "...",
|
| 79 |
-
"decision_implications": [...],
|
| 80 |
-
"watchlist": [...],
|
| 81 |
-
"top_stories": [...]
|
| 82 |
-
}
|
| 83 |
-
|
| 84 |
-
Legacy shape:
|
| 85 |
-
{
|
| 86 |
-
"summary_date": "...",
|
| 87 |
-
"short_summary": "...",
|
| 88 |
-
"key_focus": "...",
|
| 89 |
-
"top_stories": "{\"executive_summary\": ..., \"top_stories\": [...]}"
|
| 90 |
-
}
|
| 91 |
-
"""
|
| 92 |
normalized = dict(summary)
|
| 93 |
|
| 94 |
nested_summary = summary.get("summary_json") or summary.get("top_stories")
|
|
@@ -131,8 +108,8 @@ def normalize_summary_payload(summary: dict) -> dict:
|
|
| 131 |
def apply_filters(df: pd.DataFrame) -> pd.DataFrame:
|
| 132 |
st.sidebar.header("Filters")
|
| 133 |
|
| 134 |
-
label_options = sorted(df["label"].dropna().unique().tolist()) if
|
| 135 |
-
source_options = sorted(df["source"].dropna().unique().tolist()) if
|
| 136 |
|
| 137 |
default_labels = [
|
| 138 |
label
|
|
@@ -152,8 +129,8 @@ def apply_filters(df: pd.DataFrame) -> pd.DataFrame:
|
|
| 152 |
default=[],
|
| 153 |
)
|
| 154 |
|
| 155 |
-
min_date = df["published_date"].min() if not df.empty else None
|
| 156 |
-
max_date = df["published_date"].max() if not df.empty else None
|
| 157 |
|
| 158 |
date_range = None
|
| 159 |
if min_date and max_date:
|
|
@@ -207,7 +184,7 @@ def render_metrics(df: pd.DataFrame, filtered_df: pd.DataFrame) -> None:
|
|
| 207 |
c1, c2, c3, c4 = st.columns(4)
|
| 208 |
|
| 209 |
c1.metric("Articles", len(df))
|
| 210 |
-
c2.metric("
|
| 211 |
c3.metric("Sources", df["source"].nunique() if "source" in df else 0)
|
| 212 |
c4.metric("Categories", df["label"].nunique() if "label" in df else 0)
|
| 213 |
|
|
@@ -395,16 +372,19 @@ def main() -> None:
|
|
| 395 |
st.warning("No classified articles found yet. Check whether the API is live and returning data.")
|
| 396 |
return
|
| 397 |
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
|
| 404 |
-
|
|
|
|
| 405 |
render_daily_summary(summary)
|
| 406 |
|
| 407 |
-
|
|
|
|
|
|
|
| 408 |
render_article_browser(filtered_df)
|
| 409 |
|
| 410 |
|
|
|
|
| 66 |
|
| 67 |
|
| 68 |
def normalize_summary_payload(summary: dict) -> dict:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
normalized = dict(summary)
|
| 70 |
|
| 71 |
nested_summary = summary.get("summary_json") or summary.get("top_stories")
|
|
|
|
| 108 |
def apply_filters(df: pd.DataFrame) -> pd.DataFrame:
|
| 109 |
st.sidebar.header("Filters")
|
| 110 |
|
| 111 |
+
label_options = sorted(df["label"].dropna().unique().tolist()) if "label" in df else []
|
| 112 |
+
source_options = sorted(df["source"].dropna().unique().tolist()) if "source" in df else []
|
| 113 |
|
| 114 |
default_labels = [
|
| 115 |
label
|
|
|
|
| 129 |
default=[],
|
| 130 |
)
|
| 131 |
|
| 132 |
+
min_date = df["published_date"].min() if "published_date" in df and not df.empty else None
|
| 133 |
+
max_date = df["published_date"].max() if "published_date" in df and not df.empty else None
|
| 134 |
|
| 135 |
date_range = None
|
| 136 |
if min_date and max_date:
|
|
|
|
| 184 |
c1, c2, c3, c4 = st.columns(4)
|
| 185 |
|
| 186 |
c1.metric("Articles", len(df))
|
| 187 |
+
c2.metric("Shown", len(filtered_df))
|
| 188 |
c3.metric("Sources", df["source"].nunique() if "source" in df else 0)
|
| 189 |
c4.metric("Categories", df["label"].nunique() if "label" in df else 0)
|
| 190 |
|
|
|
|
| 372 |
st.warning("No classified articles found yet. Check whether the API is live and returning data.")
|
| 373 |
return
|
| 374 |
|
| 375 |
+
section = st.segmented_control(
|
| 376 |
+
"View",
|
| 377 |
+
options=["Daily Summary", "Articles"],
|
| 378 |
+
default="Daily Summary",
|
| 379 |
+
)
|
| 380 |
|
| 381 |
+
if section == "Daily Summary":
|
| 382 |
+
render_metrics(df, df)
|
| 383 |
render_daily_summary(summary)
|
| 384 |
|
| 385 |
+
elif section == "Articles":
|
| 386 |
+
filtered_df = apply_filters(df)
|
| 387 |
+
render_metrics(df, filtered_df)
|
| 388 |
render_article_browser(filtered_df)
|
| 389 |
|
| 390 |
|