Spaces:
Sleeping
Sleeping
File size: 2,257 Bytes
97873ec 476cee0 97873ec 476cee0 97873ec 476cee0 97873ec 476cee0 97873ec 476cee0 97873ec 476cee0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
"""
Background price cache with multi-API fallback and rate-limit handling
"""
import httpx
import logging
# Primary and secondary APIs for crypto prices
COINGECKO_URL = (
"https://api.coingecko.com/api/v3/simple/price"
"?ids=bitcoin,ethereum,dogecoin&vs_currencies=usd"
)
COINCAP_URL = (
"https://api.coincap.io/v2/assets?ids=bitcoin,ethereum,dogecoin"
)
# Shared price cache
CURRENT_PRICES = {"bitcoin": "--", "ethereum": "--", "dogecoin": "--"}
# How often to retry each API before falling back (seconds)
RETRY_DELAY = 5
def fetch_prices() -> None:
"""
Try CoinGecko first; on 429 or error, fall back to CoinCap.
Updates CURRENT_PRICES in-place.
"""
global CURRENT_PRICES
apis = [
("CoinGecko", COINGECKO_URL),
("CoinCap", COINCAP_URL)
]
for name, url in apis:
try:
resp = httpx.get(url, timeout=10)
# Handle CoinCap JSON structure separately
if name == "CoinGecko":
resp.raise_for_status()
data = resp.json()
prices = {
"bitcoin": data["bitcoin"]["usd"],
"ethereum": data["ethereum"]["usd"],
"dogecoin": data["dogecoin"]["usd"]
}
else:
resp.raise_for_status()
data = resp.json().get("data", [])
prices = {item["id"]: float(item["priceUsd"]) for item in data}
CURRENT_PRICES.update(prices)
logging.info("✅ [%s] prices updated: %s", name, prices)
return
except httpx.HTTPStatusError as e:
status = e.response.status_code
if status == 429:
logging.warning("⚠️ [%s] rate limit (429). Retrying fallback.", name)
else:
logging.warning("⚠️ [%s] HTTP error %s: %s", name, status, e)
except Exception as e:
logging.warning("⚠️ [%s] fetch error: %s", name, e)
# If we reach here, wait a bit before trying next API
try:
import time; time.sleep(RETRY_DELAY)
except Exception:
pass
logging.error("❌ All price APIs failed. Keeping previous prices: %s", CURRENT_PRICES)
|