Spaces:
Paused
Paused
zt p commited on
Commit ·
cd60f2f
1
Parent(s): ce673a5
Handle blocked market data endpoints
Browse files- app/monitors/market_move.py +32 -4
- coinpush.py +16 -11
app/monitors/market_move.py
CHANGED
|
@@ -331,25 +331,49 @@ class PublicMarketDataClient:
|
|
| 331 |
self.session = requests.Session()
|
| 332 |
self.session.headers.update(legacy.REQ_HEADERS)
|
| 333 |
self.last_error_log = {}
|
|
|
|
| 334 |
self._upbit_krw_usdt = None
|
| 335 |
|
| 336 |
def update_config(self, config):
|
| 337 |
self.config = normalize_config(config)
|
| 338 |
|
| 339 |
-
def _log_error_once(self, key, message, cooldown=600):
|
| 340 |
now = time.time()
|
| 341 |
if now - self.last_error_log.get(key, 0) >= cooldown:
|
| 342 |
self.last_error_log[key] = now
|
| 343 |
-
self.logger(message, level=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
|
| 345 |
def _get_json(self, base, path, params=None, timeout=12):
|
|
|
|
|
|
|
| 346 |
url = base.rstrip("/") + path
|
| 347 |
last_exc = None
|
| 348 |
for attempt in range(2):
|
| 349 |
try:
|
| 350 |
resp = self.session.get(url, params=params, timeout=timeout)
|
| 351 |
if resp.status_code != 200:
|
| 352 |
-
self.
|
|
|
|
|
|
|
| 353 |
return None
|
| 354 |
return resp.json()
|
| 355 |
except Exception as exc:
|
|
@@ -360,13 +384,17 @@ class PublicMarketDataClient:
|
|
| 360 |
return None
|
| 361 |
|
| 362 |
def _post_json(self, base, path, body=None, timeout=12):
|
|
|
|
|
|
|
| 363 |
url = base.rstrip("/") + path
|
| 364 |
last_exc = None
|
| 365 |
for attempt in range(2):
|
| 366 |
try:
|
| 367 |
resp = self.session.post(url, json=body or {}, timeout=timeout)
|
| 368 |
if resp.status_code != 200:
|
| 369 |
-
self.
|
|
|
|
|
|
|
| 370 |
return None
|
| 371 |
return resp.json()
|
| 372 |
except Exception as exc:
|
|
|
|
| 331 |
self.session = requests.Session()
|
| 332 |
self.session.headers.update(legacy.REQ_HEADERS)
|
| 333 |
self.last_error_log = {}
|
| 334 |
+
self.blocked_until = {}
|
| 335 |
self._upbit_krw_usdt = None
|
| 336 |
|
| 337 |
def update_config(self, config):
|
| 338 |
self.config = normalize_config(config)
|
| 339 |
|
| 340 |
+
def _log_error_once(self, key, message, cooldown=600, level="error"):
|
| 341 |
now = time.time()
|
| 342 |
if now - self.last_error_log.get(key, 0) >= cooldown:
|
| 343 |
self.last_error_log[key] = now
|
| 344 |
+
self.logger(message, level=level)
|
| 345 |
+
|
| 346 |
+
def _blocked_key(self, method, base, path):
|
| 347 |
+
return method, base.rstrip("/"), path
|
| 348 |
+
|
| 349 |
+
def _block_for_status(self, method, base, path, status_code):
|
| 350 |
+
if status_code not in (403, 451, 429):
|
| 351 |
+
return
|
| 352 |
+
cooldown = 3600 if status_code in (403, 451) else 120
|
| 353 |
+
self.blocked_until[self._blocked_key(method, base, path)] = time.time() + cooldown
|
| 354 |
+
mins = max(1, int(cooldown / 60))
|
| 355 |
+
self._log_error_once(
|
| 356 |
+
(base, path, status_code),
|
| 357 |
+
f"{base}{path} 状态码 {status_code},临时跳过 {mins} 分钟并使用其他交易所行情",
|
| 358 |
+
cooldown=cooldown,
|
| 359 |
+
level="info",
|
| 360 |
+
)
|
| 361 |
+
|
| 362 |
+
def _is_blocked(self, method, base, path):
|
| 363 |
+
return time.time() < self.blocked_until.get(self._blocked_key(method, base, path), 0)
|
| 364 |
|
| 365 |
def _get_json(self, base, path, params=None, timeout=12):
|
| 366 |
+
if self._is_blocked("GET", base, path):
|
| 367 |
+
return None
|
| 368 |
url = base.rstrip("/") + path
|
| 369 |
last_exc = None
|
| 370 |
for attempt in range(2):
|
| 371 |
try:
|
| 372 |
resp = self.session.get(url, params=params, timeout=timeout)
|
| 373 |
if resp.status_code != 200:
|
| 374 |
+
self._block_for_status("GET", base, path, resp.status_code)
|
| 375 |
+
if resp.status_code not in (403, 451, 429):
|
| 376 |
+
self._log_error_once((base, path, resp.status_code), f"{base}{path} 状态码 {resp.status_code}")
|
| 377 |
return None
|
| 378 |
return resp.json()
|
| 379 |
except Exception as exc:
|
|
|
|
| 384 |
return None
|
| 385 |
|
| 386 |
def _post_json(self, base, path, body=None, timeout=12):
|
| 387 |
+
if self._is_blocked("POST", base, path):
|
| 388 |
+
return None
|
| 389 |
url = base.rstrip("/") + path
|
| 390 |
last_exc = None
|
| 391 |
for attempt in range(2):
|
| 392 |
try:
|
| 393 |
resp = self.session.post(url, json=body or {}, timeout=timeout)
|
| 394 |
if resp.status_code != 200:
|
| 395 |
+
self._block_for_status("POST", base, path, resp.status_code)
|
| 396 |
+
if resp.status_code not in (403, 451, 429):
|
| 397 |
+
self._log_error_once((base, path, resp.status_code), f"{base}{path} 状态码 {resp.status_code}")
|
| 398 |
return None
|
| 399 |
return resp.json()
|
| 400 |
except Exception as exc:
|
coinpush.py
CHANGED
|
@@ -1373,17 +1373,22 @@ class CoreMarketAggregator:
|
|
| 1373 |
|
| 1374 |
def _get_json(self, base, path, params=None, method="GET", body=None, timeout=6):
|
| 1375 |
url = base.rstrip("/") + path
|
| 1376 |
-
|
| 1377 |
-
|
| 1378 |
-
|
| 1379 |
-
|
| 1380 |
-
|
| 1381 |
-
|
| 1382 |
-
|
| 1383 |
-
|
| 1384 |
-
|
| 1385 |
-
|
| 1386 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1387 |
|
| 1388 |
def aggregate(self, coin_name, coin_cfg, snapshot=None):
|
| 1389 |
symbol = (coin_cfg or {}).get("symbol")
|
|
|
|
| 1373 |
|
| 1374 |
def _get_json(self, base, path, params=None, method="GET", body=None, timeout=6):
|
| 1375 |
url = base.rstrip("/") + path
|
| 1376 |
+
last_exc = None
|
| 1377 |
+
for attempt in range(2):
|
| 1378 |
+
try:
|
| 1379 |
+
if method == "POST":
|
| 1380 |
+
resp = self.session.post(url, json=body or {}, timeout=timeout)
|
| 1381 |
+
else:
|
| 1382 |
+
resp = self.session.get(url, params=params, timeout=timeout)
|
| 1383 |
+
if resp.status_code != 200:
|
| 1384 |
+
return None
|
| 1385 |
+
return resp.json()
|
| 1386 |
+
except Exception as exc:
|
| 1387 |
+
last_exc = exc
|
| 1388 |
+
if attempt == 0:
|
| 1389 |
+
time.sleep(0.2)
|
| 1390 |
+
self._log_error_once((base, path, "exception"), f"⚠️ 聚合行情 {base}{path} 异常: {last_exc}")
|
| 1391 |
+
return None
|
| 1392 |
|
| 1393 |
def aggregate(self, coin_name, coin_cfg, snapshot=None):
|
| 1394 |
symbol = (coin_cfg or {}).get("symbol")
|