Skip to content

Implement live score fetching for World Cup 2026 - #3

Merged
pangwangshu merged 7 commits into
mainfrom
feature/live-scores
Jun 11, 2026
Merged

pangwangshu merged 7 commits into
mainfrom
feature/live-scores

Conversation

@pangwangshu

Copy link
Copy Markdown
Owner

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 thread src/live_scores.py Outdated
Comment on lines +265 to +267
full_time = provider_match.get("score", {}).get("fullTime", {})
if not isinstance(full_time, dict):
full_time = {}
Comment thread src/prediction_cache.py
Comment thread src/ui.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.

Comment thread src/ui.py
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 thread src/engine.py
Comment thread src/live_scores.py
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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Comment thread src/ui.py
Comment thread src/live_scores.py
Comment thread src/api.py
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
pangwangshu and others added 2 commits June 10, 2026 22:47
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>
@pangwangshu
pangwangshu merged commit f722cb6 into main Jun 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants