Add diskcache finctionality for caching sports api fixtures.

This commit is contained in:
2026-03-22 12:22:31 +01:00
parent 0cbb772dc4
commit ebf8c78c79
3 changed files with 25 additions and 13 deletions

View File

@@ -14,7 +14,8 @@ dependencies = [
"openpyxl>=3.1.0",
"PyYaml==6.0.3",
"playwright==1.58.0",
"requests>=2.32.0"
"requests>=2.32.0",
"diskcache>=5.6",
]
[project.optional-dependencies]

View File

@@ -5,3 +5,4 @@ from pydantic.dataclasses import dataclass
class ResolverConfig:
api_key: str
league_map: dict[str, int]
cache_path: str = "data/fixture_cache"

View File

@@ -5,6 +5,7 @@ from difflib import SequenceMatcher
from enum import Enum
from typing import Any
import diskcache
import requests
from beaky import _ansi
@@ -83,6 +84,7 @@ class TicketResolver:
def __init__(self, config: ResolverConfig):
self._headers = {"x-apisports-key": config.api_key}
self._league_map = config.league_map
self._disk_cache: diskcache.Cache = diskcache.Cache(config.cache_path)
# Cache maps (center_date_str, league_id | None) -> list of fixture dicts
self._fixture_cache: dict[tuple[str, int | None], list[dict[str, Any]]] = {}
# Cache maps league name -> (league_id, confidence)
@@ -150,6 +152,10 @@ class TicketResolver:
cache_key = (date_str, league_id)
if cache_key not in self._fixture_cache:
if cache_key in self._disk_cache:
self._fixture_cache[cache_key] = self._disk_cache[cache_key]
print(_ansi.gray(f" │ /fixtures served from disk cache ({len(self._fixture_cache[cache_key])} fixtures)"))
else:
date_from = (center - timedelta(days=_DATE_WINDOW)).strftime("%Y-%m-%d")
date_to = (center + timedelta(days=_DATE_WINDOW)).strftime("%Y-%m-%d")
params: dict[str, str | int] = {"from": date_from, "to": date_to}
@@ -160,9 +166,13 @@ class TicketResolver:
resp = _get(f"{_API_BASE}/fixtures", headers=self._headers, params=params)
resp.raise_for_status()
self._fixture_cache[cache_key] = resp.json().get("response", [])
print(_ansi.gray(f"{len(self._fixture_cache[cache_key])} fixtures returned (cached)"))
print(_ansi.gray(f"{len(self._fixture_cache[cache_key])} fixtures returned"))
finished = [f for f in self._fixture_cache[cache_key] if _is_finished(f) == 1.0]
if finished:
self._disk_cache[cache_key] = finished
print(_ansi.gray(f"{len(finished)} finished fixture(s) written to disk cache"))
else:
print(_ansi.gray(f" │ /fixtures (±{_DATE_WINDOW}d of {date_str}, league={league_id}) served from cache"))
print(_ansi.gray(f" │ /fixtures (±{_DATE_WINDOW}d of {date_str}, league={league_id}) served from memory"))
fixture, name_match, date_prox = _best_fixture_match(
self._fixture_cache[cache_key], bet.team1Name, bet.team2Name, center