Implement live score fetching for World Cup 2026 - #3
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds end-to-end “live scores” support for the 2026 World Cup: fetching results from football-data.org, persisting a normalized snapshot to disk, merging it into the engine’s match-result state, and exposing refresh/status surfaces via both the API and Streamlit UI. It also introduces cache invalidation so predictions are recomputed after score updates.
Changes:
- Add live score fetching + snapshot normalization/persistence (
src/live_scores.py) and merge live results into engine result-state loading (src/engine.py). - Add API + UI controls to refresh scores and view score snapshot status, clearing prediction caches after refresh (
src/api.py,src/ui.py,src/prediction_cache.py). - Add test coverage for live score normalization, engine merging, API endpoints, and cache clearing behavior (multiple
tests/*), plus docs/ignore updates.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_prediction_cache.py | Adds coverage that PredictionCacheService.clear() drops cached predictions. |
| tests/test_live_scores.py | Adds unit tests for live-score snapshot normalization and unmatched-provider reporting. |
| tests/test_engine.py | Adds tests asserting live results merge into match result state and interact with rule-based pairing. |
| tests/test_api.py | Adds tests for startup refresh behavior and new /refresh-scores + /score-status endpoints. |
| src/ui.py | Adds “Refresh scores” button and renders live score status in the Streamlit UI. |
| src/prediction_cache.py | Adds clear() to invalidate cached predictions after score refreshes. |
| src/live_scores.py | New module implementing football-data.org fetcher, normalization, snapshot model, and persistence. |
| src/engine.py | Adds live-results loading, merges live+manual results, and adds predictor methods for refresh/status. |
| src/api.py | Adds startup live-score refresh and two new endpoints for refresh/status. |
| README.md | Documents football-data.org token usage and new live-score endpoints/storage. |
| data/polymarket_last_snapshot.json | Updates bundled Polymarket snapshot data. |
| .gitignore | Ignores data/live_results_2026.json snapshot file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+265
to
+267
| full_time = provider_match.get("score", {}).get("fullTime", {}) | ||
| if not isinstance(full_time, dict): | ||
| full_time = {} |
Comment on lines
+270
to
+272
| predictor.refresh_live_scores() | ||
| get_prediction_cache(strength_mode, market_ttl_seconds).clear() | ||
| st.success("Live scores refreshed.") |
Comment on lines
+195
to
+203
| local_fixed_matches: list[dict[str, Any]] = [] | ||
| for local in world_cup_data.get("schedule", []): | ||
| if not isinstance(local, dict) or not isinstance(local.get("match_number"), int): | ||
| continue | ||
| fixed = parse_fixed_matchup_text(str(local.get("matchup") or local.get("comment") or "")) | ||
| if fixed is None: | ||
| continue | ||
| home = normalizer.resolve(fixed[0]) | ||
| away = normalizer.resolve(fixed[1]) |
Comment on lines
1
to
4
| { | ||
| "fetched_at_epoch": 1780961192.5492675, | ||
| "fetched_at_epoch": 1781154631.324947, | ||
| "events_seen": 72, | ||
| "market_selections": [ |
…ll prediction caches, revert unrelated polymarket snapshot
Comment on lines
+64
to
+71
| @app.post("/refresh-scores") | ||
| def refresh_scores() -> dict: | ||
| try: | ||
| status = predictor.refresh_live_scores() | ||
| except Exception as exc: | ||
| raise HTTPException(status_code=502, detail=str(exc)) from exc | ||
| prediction_cache.clear() | ||
| return status |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce functionality to fetch and manage live scores for the World Cup 2026, including API endpoints for refreshing scores and checking score status. Clear cached predictions upon score refresh to ensure up-to-date information.