PaperTrade / request_context.py
Khanna, Videh Rakesh Rakesh
feat: add Ollama fallback, request context, and cached OHLCV helpers
385ef79
Raw
History Blame Contribute Delete
1.94 kB
"""
request_context.py - Request-scoped tracking for predictions.
Tracks a single prediction request: timing, data sources, merges, validation.
Used to diagnose why predictions succeed or timeout.
"""
import uuid
import time
import logging
from datetime import datetime
logger = logging.getLogger(__name__)
class RequestContext:
"""Tracks a single prediction request: timing, data sources, merges."""
def __init__(self, ticker: str = ""):
self.request_id = str(uuid.uuid4())[:8]
self.ticker = ticker
self.start_time = time.time()
self.merge_log = []
self.validation_log = []
def elapsed(self) -> float:
"""Seconds elapsed since request start."""
return time.time() - self.start_time
def log_data_merge(self, source: str, data_rows: int, live_price: float):
"""Log a data merge (cached OHLCV + live price)."""
self.merge_log.append({
"source": source,
"rows": data_rows,
"live_price": live_price,
"timestamp": time.time()
})
logger.info(f"[{self.request_id}] Merged {data_rows} cached rows with live price ₹{live_price:.2f}")
def log_validation(self, cached_ticker: str, expected_ticker: str, is_match: bool):
"""Log ticker validation before merge."""
self.validation_log.append({
"cached": cached_ticker,
"expected": expected_ticker,
"match": is_match
})
status = "✓" if is_match else "✗"
logger.info(f"[{self.request_id}] {status} Data validation: {cached_ticker} vs {expected_ticker}")
def get_merge_report(self) -> dict:
"""Return merge details for API response."""
return {
"request_id": self.request_id,
"merges": len(self.merge_log),
"validations": self.validation_log,
"elapsed_ms": int(self.elapsed() * 1000),
}