#!/usr/bin/env python3 """LobeHub API Gateway — 601 ключей, 20 моделей, closerouter backend""" import json, time, httpx, secrets from http.server import HTTPServer, BaseHTTPRequestHandler from pathlib import Path BASE_URL = "http://[REDACTED-IP]:3210" BACKEND = "https://api.closerouter.dev/v1" BACKEND_KEY = "closerouter_G7GChTmljnOmIlJaD92YKaIzLHeMjErvbrKEBRxhsCY" PORT = 20141 KEYS_FILE = Path(r"C:\Users\User\lobehub_api_keys.json") TOKEN_CACHE = {} # email → token cache MODELS = [ "claude-opus-4.8","claude-opus-4.7","claude-opus-4.6","claude-opus-4.5", "claude-sonnet-5","claude-sonnet-4.6","claude-sonnet-4.5","claude-haiku-4.5", "gpt-5.5","gpt-5.4","gpt-5.4-mini","gpt-5.3-codex-spark", "deepseek-v4-pro","deepseek-v4-flash", "glm-5.2","glm-5.1","kimi-k2.7-code","kimi-k2.6", "qwen-3.7-plus","qwen-3.7-max", ] MODEL_PREFIX = { "claude": "anthropic/", "gpt": "openai/", "deepseek": "deepseek/", "glm": "z-ai/", "kimi": "moonshotai/", "qwen": "qwen/", } with open(KEYS_FILE) as f: KEY_DATA = json.load(f) KEYS = {k['api_key']: k for k in KEY_DATA['keys']} print(f"[Gateway] {len(KEYS)} keys | {len(MODELS)} models | closerouter backend") def resolve_model(model): for prefix, provider in MODEL_PREFIX.items(): if model.startswith(prefix): return f"{provider}{model}" return model def get_token(email, pw): cache_key = f"{email}:{pw}" if cache_key in TOKEN_CACHE: cached = TOKEN_CACHE[cache_key] if cached['expires'] > time.time(): return cached['token'] try: r = httpx.post(f"{BASE_URL}/api/auth/sign-in/email", json={"email": email, "password": pw}, headers={"Origin": BASE_URL, "Referer": f"{BASE_URL}/signin"}, timeout=10) if r.status_code == 200 and "token" in r.json(): token = [REDACTED])["token"] TOKEN_CACHE[cache_key] = {"token": token, "expires": time.time() + 3600} return token except: pass return None class Gateway(BaseHTTPRequestHandler): def _json(self, data, status=200): self.send_response(status) self.send_header("Content-Type", "application/json") self.send_header("Access-Control-Allow-Origin", "*") self.end_headers() self.wfile.write(json.dumps(data, ensure_ascii=False).encode()) def _auth(self): auth = self.headers.get("Authorization", "") if not auth.startswith("Bearer "): return None key = auth[7:] if key == "local": return {"email": "local", "password": "local"} if key in KEYS: return KEYS[key] if ":" in key and "@" in key: e, p = key.split(":", 1) return {"email": e, "password": p} return None def do_GET(self): if self.path == "/health": self._json({"status": "ok", "keys": len(KEYS), "models": len(MODELS), "backend": "closerouter"}) elif self.path == "/v1/models": self._json({"object": "list", "data": [{"id": m, "object": "model"} for m in MODELS]}) elif self.path == "/keys/stats": self._json({"total": len(KEYS), "cached_tokens": len(TOKEN_CACHE)}) else: self._json({"error": "not found"}, 404) def do_POST(self): if self.path == "/v1/chat/completions": self._chat() elif self.path == "/v1/embeddings": self._json({"error": "embeddings not supported"}, 400) else: self._json({"error": "not found"}, 404) def _chat(self): account = self._auth() if not account: self._json({"error": "Unauthorized. Use Bearer or Bearer local"}, 401) return try: body = json.loads(self.rfile.read(int(self.headers.get("Content-Length", 0)))) except: self._json({"error": "Invalid JSON"}, 400); return model = body.get("model", "deepseek-v4-pro") messages = body.get("messages", []) if not messages: self._json({"error": "messages required"}, 400); return backend_model = resolve_model(model) try: r = httpx.post(f"{BACKEND}/chat/completions", headers={"Authorization": f"Bearer {BACKEND_KEY}", "Content-Type": "application/json"}, json={ "model": backend_model, "messages": messages, "max_tokens": body.get("max_tokens", 4096), "stream": False, }, timeout=180) if r.status_code == 200: self._json(r.json()) else: self._json({"error": f"Backend {r.status_code}: {r.text[:300]}"}, 500) except Exception as e: self._json({"error": str(e)}, 500) def log_message(self, f, *a): pass print(f"[Gateway] :{PORT} | {len(KEYS)} keys | 20 models | closerouter") while True: try: HTTPServer(("127.0.0.1", PORT), Gateway).serve_forever() except Exception as e: print(f"[Gateway] Restart: {e}") time.sleep(3)