zt p commited on
Commit
cd60f2f
·
1 Parent(s): ce673a5

Handle blocked market data endpoints

Browse files
Files changed (2) hide show
  1. app/monitors/market_move.py +32 -4
  2. 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="error")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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._log_error_once((base, path, resp.status_code), f"{base}{path} 状态码 {resp.status_code}")
 
 
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._log_error_once((base, path, resp.status_code), f"{base}{path} 状态码 {resp.status_code}")
 
 
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
- try:
1377
- if method == "POST":
1378
- resp = self.session.post(url, json=body or {}, timeout=timeout)
1379
- else:
1380
- resp = self.session.get(url, params=params, timeout=timeout)
1381
- if resp.status_code != 200:
1382
- return None
1383
- return resp.json()
1384
- except Exception as exc:
1385
- self._log_error_once((base, path, "exception"), f"⚠️ 聚合行情 {base}{path} 异常: {exc}")
1386
- return None
 
 
 
 
 
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")