Files
JiriUhlir 0e05fef335 first
2026-07-16 11:56:15 +02:00

52 lines
1.5 KiB
Python

"""In-memory cache OAuth Bearer tokenů PPL CPL API.
PPL vydá max. 12 tokenů za minutu a token platí 30 minut — generovat token
per-request nelze. Cache je klíčovaná SHA-256 hashem přihlašovacích údajů
(samotné údaje se neukládají) a token se obnovuje s předstihem před expirací.
Per-key asyncio.Lock brání souběžnému vyžádání tokenu pro stejné údaje
(thundering herd při paralelních requestech).
"""
import asyncio
import time
from .config import TOKEN_REFRESH_MARGIN_SECONDS
# cache_key -> (access_token, expires_at_monotonic)
_tokens: dict[str, tuple[str, float]] = {}
_locks: dict[str, asyncio.Lock] = {}
def _lock_for(cache_key: str) -> asyncio.Lock:
lock = _locks.get(cache_key)
if lock is None:
lock = asyncio.Lock()
_locks[cache_key] = lock
return lock
def get_cached(cache_key: str) -> str | None:
entry = _tokens.get(cache_key)
if entry is None:
return None
token, expires_at = entry
if time.monotonic() >= expires_at:
_tokens.pop(cache_key, None)
return None
return token
def store(cache_key: str, token: str, expires_in_seconds: float) -> None:
expires_at = time.monotonic() + max(
expires_in_seconds - TOKEN_REFRESH_MARGIN_SECONDS, 30.0
)
_tokens[cache_key] = (token, expires_at)
def invalidate(cache_key: str) -> None:
_tokens.pop(cache_key, None)
async def acquire_lock(cache_key: str) -> asyncio.Lock:
return _lock_for(cache_key)