Spaces:
Running
Running
Download analytics/brief_diff.py from Viney/readthrough: direct link, hf CLI and curl.
- Browser
- Download file 2.33 kB
-
https://huggingface.co/spaces/Viney/readthrough/resolve/main/analytics/brief_diff.py
- Command line
-
hf download hf://spaces/Viney/readthrough/analytics/brief_diff.py
-
curl -L -o brief_diff.py https://huggingface.co/spaces/Viney/readthrough/resolve/main/analytics/brief_diff.py
2.33 kB
| """analytics/brief_diff.py — compare two briefs to surface what changed. | |
| Pure and Streamlit-free, like dashboard/signal_feed.py. Reuses the same | |
| fingerprinting the Signals dedup pass uses (dashboard.signal_feed._fingerprint) | |
| so "new this time" isn't fooled by minor rewording between two runs of the | |
| same underlying fact. | |
| """ | |
| from __future__ import annotations | |
| from dashboard.signal_feed import _fingerprint, build_feed | |
| def _fingerprinted_texts(brief: dict) -> dict[str, str]: | |
| """Map fingerprint -> display text for every non-LOW signal in *brief*. | |
| Only HIGH/MEDIUM significance participates — a diff that surfaces every | |
| LOW-significance restatement is noise, not a "what changed" summary. | |
| """ | |
| out: dict[str, str] = {} | |
| for sig in build_feed(brief): | |
| if sig.significance == "LOW": | |
| continue | |
| text = sig.headline or sig.body | |
| if not text: | |
| continue | |
| key = _fingerprint(text) | |
| if len(key.split()) < 3: | |
| continue | |
| out.setdefault(key, text) | |
| return out | |
| def diff_briefs(current: dict, previous: dict) -> dict: | |
| """Compare two briefs for the same ticker and return what changed. | |
| Returns: | |
| { | |
| "new_signals": [str, ...], # present now, absent from `previous` | |
| "resolved_signals": [str, ...], # present in `previous`, absent now | |
| "sentiment_shift": {"previous": str, "current": str} | None, | |
| "previous_generated_at": str, | |
| } | |
| """ | |
| curr_texts = _fingerprinted_texts(current) | |
| prev_texts = _fingerprinted_texts(previous) | |
| new_signals = [text for key, text in curr_texts.items() if key not in prev_texts] | |
| resolved_signals = [text for key, text in prev_texts.items() if key not in curr_texts] | |
| sentiment_shift = None | |
| curr_label = ((current.get("sentiment") or {}).get("metrics") or {}).get("label") | |
| prev_label = ((previous.get("sentiment") or {}).get("metrics") or {}).get("label") | |
| if curr_label and prev_label and curr_label != prev_label: | |
| sentiment_shift = {"previous": prev_label, "current": curr_label} | |
| return { | |
| "new_signals": new_signals[:5], | |
| "resolved_signals": resolved_signals[:5], | |
| "sentiment_shift": sentiment_shift, | |
| "previous_generated_at": previous.get("generated_at", ""), | |
| } | |