from __future__ import annotations import os from datetime import datetime, timezone import requests from .bitstamp_rate_limit import throttle_bitstamp_request from .storage import get_connection BITSTAMP_BASE_URL = "https://www.bitstamp.net" FX_REFRESH_SECONDS = 15 * 60 FX_CACHE_TTL_SECONDS = 60 def fetch_eur_usd() -> dict: cache_key = "bitstamp:fx:eur_usd" cached = __import__("exec_mcp.repo", fromlist=["cache_get"]).cache_get(cache_key) if cached is not None: return cached throttle_bitstamp_request() response = requests.get(f"{BITSTAMP_BASE_URL}/api/v2/eur_usd/", timeout=30) response.raise_for_status() payload = response.json() __import__("exec_mcp.repo", fromlist=["cache_put"]).cache_put( cache_key, payload, max(int(os.getenv("BITSTAMP_FX_CACHE_TTL_SECONDS", str(FX_CACHE_TTL_SECONDS))), 0), ) return payload def save_eur_usd(payload: dict) -> None: captured_at = datetime.now(timezone.utc).isoformat() with get_connection() as conn: conn.execute( """ INSERT INTO bitstamp_fx_rates (pair, buy, sell, payload_json, captured_at) VALUES (?, ?, ?, ?, ?) ON CONFLICT(pair) DO UPDATE SET buy=excluded.buy, sell=excluded.sell, payload_json=excluded.payload_json, captured_at=excluded.captured_at """, ( "eur_usd", str(payload.get("buy", "")), str(payload.get("sell", "")), __import__("json").dumps(payload), captured_at, ), ) conn.commit() def load_eur_usd() -> dict | None: with get_connection() as conn: row = conn.execute("SELECT buy, sell, payload_json FROM bitstamp_fx_rates WHERE pair = ?", ("eur_usd",)).fetchone() if row is None: return None return __import__("json").loads(row["payload_json"]) def refresh_eur_usd() -> dict: payload = fetch_eur_usd() save_eur_usd(payload) return payload