Prechádzať zdrojové kódy

Add short-lived Bitstamp caches

Lukas Goldschmidt 1 mesiac pred
rodič
commit
484485ccee

+ 13 - 1
src/exec_mcp/bitstamp_fx.py

@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import os
 from datetime import datetime, timezone
 
 import requests
@@ -9,13 +10,24 @@ 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()
-    return response.json()
+    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:

+ 24 - 2
src/exec_mcp/bitstamp_metadata.py

@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import os
 import requests
 
 from .bitstamp_rate_limit import throttle_bitstamp_request
@@ -7,20 +8,41 @@ from .storage import get_connection
 
 BITSTAMP_BASE_URL = "https://www.bitstamp.net"
 METADATA_REFRESH_SECONDS = 24 * 60 * 60
+METADATA_CACHE_TTL_SECONDS = 60
 
 
 def fetch_currencies() -> list[dict]:
+    cache_key = "bitstamp:metadata:currencies"
+    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/currencies/", timeout=30)
     response.raise_for_status()
-    return response.json()
+    payload = response.json()
+    __import__("exec_mcp.repo", fromlist=["cache_put"]).cache_put(
+        cache_key,
+        payload,
+        max(int(os.getenv("BITSTAMP_METADATA_CACHE_TTL_SECONDS", str(METADATA_CACHE_TTL_SECONDS))), 0),
+    )
+    return payload
 
 
 def fetch_markets() -> list[dict]:
+    cache_key = "bitstamp:metadata:markets"
+    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/markets/", timeout=30)
     response.raise_for_status()
-    return response.json()
+    payload = response.json()
+    __import__("exec_mcp.repo", fromlist=["cache_put"]).cache_put(
+        cache_key,
+        payload,
+        max(int(os.getenv("BITSTAMP_METADATA_CACHE_TTL_SECONDS", str(METADATA_CACHE_TTL_SECONDS))), 0),
+    )
+    return payload
 
 
 def save_metadata(kind: str, payload: list[dict]) -> None:

+ 9 - 2
src/exec_mcp/services_bitstamp.py

@@ -12,6 +12,13 @@ BALANCE_CACHE_TTL_SECONDS = 20
 ACCOUNT_INFO_CACHE_TTL_SECONDS = 30
 
 
+def _ttl_from_env(name: str, default_seconds: int) -> int:
+    try:
+        return max(int(__import__("os").getenv(name, str(default_seconds))), 0)
+    except Exception:
+        return default_seconds
+
+
 def _require_client() -> None:
     if bitstamp is None:
         raise RuntimeError("bitstamp-python-client dependency is not installed")
@@ -63,7 +70,7 @@ def fetch_account_balance(account_id: str) -> dict:
     normalized = _normalize_account_balances_payload(payload, account_id)
 
     result = {"source": "bitstamp", "cached": False, "balances": normalized, "payload": payload}
-    repo.cache_put(cache_key, result, BALANCE_CACHE_TTL_SECONDS)
+    repo.cache_put(cache_key, result, _ttl_from_env("BITSTAMP_BALANCE_CACHE_TTL_SECONDS", BALANCE_CACHE_TTL_SECONDS))
     return result
 
 
@@ -110,5 +117,5 @@ def fetch_account_info(account_id: str) -> dict:
         "raw_balance": balance["payload"],
     }
 
-    repo.cache_put(cache_key, result, ACCOUNT_INFO_CACHE_TTL_SECONDS)
+    repo.cache_put(cache_key, result, _ttl_from_env("BITSTAMP_ACCOUNT_INFO_CACHE_TTL_SECONDS", ACCOUNT_INFO_CACHE_TTL_SECONDS))
     return result

+ 2 - 0
tests/test_bitstamp_rate_limit.py

@@ -36,6 +36,8 @@ def test_bitstamp_public_helpers_call_throttle(monkeypatch):
     calls: list[str] = []
     monkeypatch.setattr(bitstamp_metadata, "throttle_bitstamp_request", lambda: calls.append("meta"))
     monkeypatch.setattr(bitstamp_fx, "throttle_bitstamp_request", lambda: calls.append("fx"))
+    monkeypatch.setattr("exec_mcp.repo.cache_get", lambda *args, **kwargs: None)
+    monkeypatch.setattr("exec_mcp.repo.cache_put", lambda *args, **kwargs: None)
 
     def fake_get(url, *args, **kwargs):
         if url.endswith("/currencies/"):