bitstamp_fx.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. from __future__ import annotations
  2. import os
  3. from datetime import datetime, timezone
  4. import requests
  5. from .bitstamp_rate_limit import throttle_bitstamp_request
  6. from .storage import get_connection
  7. BITSTAMP_BASE_URL = "https://www.bitstamp.net"
  8. FX_REFRESH_SECONDS = 15 * 60
  9. FX_CACHE_TTL_SECONDS = 60
  10. def fetch_eur_usd() -> dict:
  11. cache_key = "bitstamp:fx:eur_usd"
  12. cached = __import__("exec_mcp.repo", fromlist=["cache_get"]).cache_get(cache_key)
  13. if cached is not None:
  14. return cached
  15. throttle_bitstamp_request()
  16. response = requests.get(f"{BITSTAMP_BASE_URL}/api/v2/eur_usd/", timeout=30)
  17. response.raise_for_status()
  18. payload = response.json()
  19. __import__("exec_mcp.repo", fromlist=["cache_put"]).cache_put(
  20. cache_key,
  21. payload,
  22. max(int(os.getenv("BITSTAMP_FX_CACHE_TTL_SECONDS", str(FX_CACHE_TTL_SECONDS))), 0),
  23. )
  24. return payload
  25. def save_eur_usd(payload: dict) -> None:
  26. captured_at = datetime.now(timezone.utc).isoformat()
  27. with get_connection() as conn:
  28. conn.execute(
  29. """
  30. INSERT INTO bitstamp_fx_rates (pair, buy, sell, payload_json, captured_at)
  31. VALUES (?, ?, ?, ?, ?)
  32. ON CONFLICT(pair) DO UPDATE SET
  33. buy=excluded.buy,
  34. sell=excluded.sell,
  35. payload_json=excluded.payload_json,
  36. captured_at=excluded.captured_at
  37. """,
  38. (
  39. "eur_usd",
  40. str(payload.get("buy", "")),
  41. str(payload.get("sell", "")),
  42. __import__("json").dumps(payload),
  43. captured_at,
  44. ),
  45. )
  46. conn.commit()
  47. def load_eur_usd() -> dict | None:
  48. with get_connection() as conn:
  49. row = conn.execute("SELECT buy, sell, payload_json FROM bitstamp_fx_rates WHERE pair = ?", ("eur_usd",)).fetchone()
  50. if row is None:
  51. return None
  52. return __import__("json").loads(row["payload_json"])
  53. def refresh_eur_usd() -> dict:
  54. payload = fetch_eur_usd()
  55. save_eur_usd(payload)
  56. return payload