Spaces:
Configuration error
Configuration error
Niranjan-Murugarasu024
feat: TradeSense AI Chairman Edition production release ready for Hugging Face Spaces
0125724 Download backend/data/cache.py from BlueMen/tradesenseAi: direct link, hf CLI and curl.
- Browser
- Download file 7.58 kB
-
https://huggingface.co/spaces/BlueMen/tradesenseAi/resolve/main/backend/data/cache.py
- Command line
-
hf download hf://spaces/BlueMen/tradesenseAi/backend/data/cache.py
-
curl -L -o cache.py https://huggingface.co/spaces/BlueMen/tradesenseAi/resolve/main/backend/data/cache.py
7.58 kB
| """ | |
| TradeSense AI β In-Memory Market Data Cache | |
| TTL-enforced caching with rich audit metadata. API credentials are NEVER stored. | |
| """ | |
| import time | |
| from datetime import date, datetime, timezone | |
| from typing import Dict, Optional, Tuple, Any | |
| import pandas as pd | |
| from backend.config.settings import settings | |
| from backend.app.schemas.contracts import DatasetMetadata | |
| class CacheEntryMetadata: | |
| """ | |
| Audit metadata stored alongside each cached dataset. | |
| SECURITY: Must never contain API keys, auth headers, or secrets. | |
| """ | |
| __slots__ = ( | |
| "ticker", "start_date", "end_date", "cutoff_session", | |
| "dataset_version", "quality_status", "provider", | |
| "lineage_hash", "created_at", "expires_at", | |
| ) | |
| def __init__( | |
| self, | |
| ticker: str, | |
| start_date: date, | |
| end_date: date, | |
| cutoff_session: date, | |
| dataset_version: str, | |
| quality_status: str, | |
| provider: str, | |
| lineage_hash: str, | |
| ttl_seconds: int, | |
| ): | |
| self.ticker = ticker | |
| self.start_date = start_date | |
| self.end_date = end_date | |
| self.cutoff_session = cutoff_session | |
| self.dataset_version = dataset_version | |
| self.quality_status = quality_status | |
| self.provider = provider | |
| self.lineage_hash = lineage_hash | |
| self.created_at: datetime = datetime.now(timezone.utc) | |
| self.expires_at: float = time.time() + ttl_seconds | |
| def is_expired(self) -> bool: | |
| return time.time() > self.expires_at | |
| def safe_dict(self) -> Dict[str, Any]: | |
| """Returns a safe, credential-free audit snapshot of this entry.""" | |
| return { | |
| "ticker": self.ticker, | |
| "start_date": str(self.start_date), | |
| "end_date": str(self.end_date), | |
| "cutoff_session": str(self.cutoff_session), | |
| "dataset_version": self.dataset_version, | |
| "quality_status": self.quality_status, | |
| "provider": self.provider, | |
| "lineage_hash": self.lineage_hash, | |
| "created_at": self.created_at.isoformat(), | |
| "expires_at": datetime.fromtimestamp(self.expires_at, tz=timezone.utc).isoformat(), | |
| } | |
| class CacheEntry: | |
| """Stores a frozen DataFrame + DatasetMetadata pair with TTL enforcement.""" | |
| def __init__( | |
| self, | |
| df: pd.DataFrame, | |
| metadata: DatasetMetadata, | |
| ttl_seconds: int, | |
| ): | |
| self.df = df.copy() | |
| self.metadata = metadata | |
| self.cache_meta = CacheEntryMetadata( | |
| ticker=metadata.ticker, | |
| start_date=metadata.start_session, | |
| end_date=metadata.cutoff_session, | |
| cutoff_session=metadata.cutoff_session, | |
| dataset_version=metadata.dataset_version, | |
| quality_status=( | |
| metadata.quality_report.quality_status.value | |
| if metadata.quality_report else "UNKNOWN" | |
| ), | |
| provider=metadata.source_primary, | |
| lineage_hash=metadata.sha256_hash, | |
| ttl_seconds=ttl_seconds, | |
| ) | |
| def is_expired(self) -> bool: | |
| return self.cache_meta.is_expired() | |
| class MarketDataCache: | |
| """ | |
| Thread-safe in-memory cache for canonical OHLCV datasets. | |
| Enforces: | |
| - TTL expiry | |
| - Cutoff T validation on retrieval (cached data cannot bypass temporal isolation) | |
| - No credential storage | |
| """ | |
| def __init__(self): | |
| self._cache: Dict[str, CacheEntry] = {} | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Internal helpers | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _build_key(ticker: str, start_date: Any, end_date: Any, cutoff_session: Any) -> str: | |
| return f"{ticker.upper()}|{start_date}|{end_date}|{cutoff_session}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Public API | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def get( | |
| self, | |
| ticker: str, | |
| start_date: Any, | |
| end_date: Any, | |
| cutoff_session: Any, | |
| ) -> Optional[Tuple[pd.DataFrame, DatasetMetadata]]: | |
| """ | |
| Returns a cached (DataFrame, DatasetMetadata) pair if: | |
| - The cache is enabled | |
| - An unexpired entry exists for this key | |
| - The cached dataset's cutoff_session matches the requested cutoff (temporal safety) | |
| """ | |
| if not settings.market_data.cache_enabled: | |
| return None | |
| key = self._build_key(ticker, start_date, end_date, cutoff_session) | |
| entry = self._cache.get(key) | |
| if entry is None: | |
| return None | |
| if entry.is_expired(): | |
| del self._cache[key] | |
| return None | |
| # CRITICAL: Validate that the cached cutoff matches the requested cutoff. | |
| # This prevents stale cache entries from violating temporal isolation. | |
| if str(entry.cache_meta.cutoff_session) != str(cutoff_session): | |
| return None | |
| return entry.df.copy(), entry.metadata | |
| def set( | |
| self, | |
| ticker: str, | |
| start_date: Any, | |
| end_date: Any, | |
| cutoff_session: Any, | |
| df: pd.DataFrame, | |
| metadata: DatasetMetadata, | |
| is_historical: bool = True, | |
| ) -> None: | |
| """Stores a canonical dataset under the given key with appropriate TTL.""" | |
| if not settings.market_data.cache_enabled: | |
| return | |
| key = self._build_key(ticker, start_date, end_date, cutoff_session) | |
| ttl = ( | |
| settings.market_data.historical_cache_ttl_seconds | |
| if is_historical | |
| else settings.market_data.latest_data_cache_ttl_seconds | |
| ) | |
| self._cache[key] = CacheEntry(df, metadata, ttl) | |
| def get_entry_metadata( | |
| self, | |
| ticker: str, | |
| start_date: Any, | |
| end_date: Any, | |
| cutoff_session: Any, | |
| ) -> Optional[Dict[str, Any]]: | |
| """Returns safe, credential-free metadata for a cached entry.""" | |
| key = self._build_key(ticker, start_date, end_date, cutoff_session) | |
| entry = self._cache.get(key) | |
| if entry is None or entry.is_expired(): | |
| return None | |
| return entry.cache_meta.safe_dict() | |
| def invalidate(self, ticker: str) -> int: | |
| """Evicts all entries for a ticker. Returns count evicted.""" | |
| keys_to_drop = [k for k in self._cache if k.startswith(f"{ticker.upper()}|")] | |
| for k in keys_to_drop: | |
| del self._cache[k] | |
| return len(keys_to_drop) | |
| def clear(self) -> None: | |
| self._cache.clear() | |
| def stats(self) -> Dict[str, Any]: | |
| """Returns aggregate cache statistics (no credentials).""" | |
| live = sum(1 for e in self._cache.values() if not e.is_expired()) | |
| return { | |
| "total_entries": len(self._cache), | |
| "live_entries": live, | |
| "expired_entries": len(self._cache) - live, | |
| } | |
| # Global Singleton Market Data Cache | |
| data_cache = MarketDataCache() | |