Spaces:
Paused
Paused
zt p commited on
Commit ·
6efd179
1
Parent(s): 7dc58b6
Add Binance spot fallback bases
Browse files- coinpush.py +41 -15
coinpush.py
CHANGED
|
@@ -51,6 +51,14 @@ BINANCE_API_SECRET = os.getenv("BINANCE_API_SECRET")
|
|
| 51 |
SPOT_BASE = os.getenv("BINANCE_SPOT_BASE", "https://api.binance.com")
|
| 52 |
FAPI_BASE = os.getenv("BINANCE_FAPI_BASE", "https://fapi.binance.com")
|
| 53 |
FSTREAM_BASE = os.getenv("BINANCE_FSTREAM_BASE", "wss://fstream.binance.com/ws")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
FAPI_451_COOLDOWN_SEC = int(os.getenv("BINANCE_FAPI_451_COOLDOWN_SEC", "3600"))
|
| 55 |
ALPHA_BASE = os.getenv("BINANCE_ALPHA_BASE", "https://www.binance.com")
|
| 56 |
ALPHA_TOKEN_CACHE_TTL_SEC = int(os.getenv("BINANCE_ALPHA_TOKEN_CACHE_TTL_SEC", "300"))
|
|
@@ -672,30 +680,48 @@ class BinanceAPI:
|
|
| 672 |
self.session = requests.Session()
|
| 673 |
self.session.headers.update(REQ_HEADERS)
|
| 674 |
self.fapi_blocked_until = 0.0
|
|
|
|
| 675 |
if BINANCE_API_KEY:
|
| 676 |
self.session.headers.update({"X-MBX-APIKEY": BINANCE_API_KEY})
|
| 677 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 678 |
def _get(self, base, path, params=None, timeout=10):
|
| 679 |
is_fapi = base == FAPI_BASE or path.startswith("/fapi/")
|
| 680 |
now = time.time()
|
| 681 |
if is_fapi and now < self.fapi_blocked_until:
|
| 682 |
return None
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
| 688 |
-
|
| 689 |
-
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 694 |
return None
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
return None
|
| 699 |
|
| 700 |
# 现货行情
|
| 701 |
def ticker_24h(self, symbol):
|
|
|
|
| 51 |
SPOT_BASE = os.getenv("BINANCE_SPOT_BASE", "https://api.binance.com")
|
| 52 |
FAPI_BASE = os.getenv("BINANCE_FAPI_BASE", "https://fapi.binance.com")
|
| 53 |
FSTREAM_BASE = os.getenv("BINANCE_FSTREAM_BASE", "wss://fstream.binance.com/ws")
|
| 54 |
+
SPOT_FALLBACK_BASES = [
|
| 55 |
+
base.strip().rstrip("/")
|
| 56 |
+
for base in os.getenv(
|
| 57 |
+
"BINANCE_SPOT_FALLBACK_BASES",
|
| 58 |
+
"https://data-api.binance.vision,https://api1.binance.com,https://api2.binance.com,https://api3.binance.com",
|
| 59 |
+
).split(",")
|
| 60 |
+
if base.strip()
|
| 61 |
+
]
|
| 62 |
FAPI_451_COOLDOWN_SEC = int(os.getenv("BINANCE_FAPI_451_COOLDOWN_SEC", "3600"))
|
| 63 |
ALPHA_BASE = os.getenv("BINANCE_ALPHA_BASE", "https://www.binance.com")
|
| 64 |
ALPHA_TOKEN_CACHE_TTL_SEC = int(os.getenv("BINANCE_ALPHA_TOKEN_CACHE_TTL_SEC", "300"))
|
|
|
|
| 680 |
self.session = requests.Session()
|
| 681 |
self.session.headers.update(REQ_HEADERS)
|
| 682 |
self.fapi_blocked_until = 0.0
|
| 683 |
+
self.spot_fallback_logged = set()
|
| 684 |
if BINANCE_API_KEY:
|
| 685 |
self.session.headers.update({"X-MBX-APIKEY": BINANCE_API_KEY})
|
| 686 |
|
| 687 |
+
def _bases_for(self, base):
|
| 688 |
+
if base != SPOT_BASE:
|
| 689 |
+
return [base]
|
| 690 |
+
bases = [SPOT_BASE.rstrip("/")]
|
| 691 |
+
for candidate in SPOT_FALLBACK_BASES:
|
| 692 |
+
if candidate and candidate not in bases:
|
| 693 |
+
bases.append(candidate)
|
| 694 |
+
return bases
|
| 695 |
+
|
| 696 |
def _get(self, base, path, params=None, timeout=10):
|
| 697 |
is_fapi = base == FAPI_BASE or path.startswith("/fapi/")
|
| 698 |
now = time.time()
|
| 699 |
if is_fapi and now < self.fapi_blocked_until:
|
| 700 |
return None
|
| 701 |
+
last_error = None
|
| 702 |
+
for current_base in self._bases_for(base):
|
| 703 |
+
try:
|
| 704 |
+
r = self.session.get(current_base + path, params=params, timeout=timeout)
|
| 705 |
+
except Exception as e:
|
| 706 |
+
last_error = f"异常 {e} ({current_base})"
|
| 707 |
+
continue
|
| 708 |
+
if r.status_code == 200:
|
| 709 |
+
if current_base != base.rstrip("/"):
|
| 710 |
+
key = (path, current_base)
|
| 711 |
+
if key not in self.spot_fallback_logged:
|
| 712 |
+
self.logger(f"ℹ️ Binance 现货主源不可用,已切换备用行情 {current_base}")
|
| 713 |
+
self.spot_fallback_logged.add(key)
|
| 714 |
+
return r.json()
|
| 715 |
+
if is_fapi and r.status_code == 451:
|
| 716 |
+
self.fapi_blocked_until = now + FAPI_451_COOLDOWN_SEC
|
| 717 |
+
mins = max(1, int(FAPI_451_COOLDOWN_SEC / 60))
|
| 718 |
+
self.logger(
|
| 719 |
+
f"⚠️ Binance 合约接口 /fapi 当前区域受限(451),"
|
| 720 |
+
f"暂停直连 {mins} 分钟并使用备用行情")
|
| 721 |
return None
|
| 722 |
+
last_error = f"状态码 {r.status_code} ({current_base})"
|
| 723 |
+
self.logger(f"⚠️ 接口 {path} {last_error or '无可用响应'}")
|
| 724 |
+
return None
|
|
|
|
| 725 |
|
| 726 |
# 现货行情
|
| 727 |
def ticker_24h(self, symbol):
|