""" OpenAI-compatible proxy on localhost:8080 Backend: dashscope deepseek-v4-pro (HERMES_DASHSCOPE_API_KEY) Auth: Bearer token check Usage: python proxy_handler.py Endpoints: GET /v1/models — list available models POST /v1/chat/completions — forward to dashscope (streaming supported) GET /health — health check (no auth needed) """ import json, sys, os, time, uuid, ssl from pathlib import Path from http.server import HTTPServer, BaseHTTPRequestHandler import urllib.request, urllib.error PORT = 8080 TOKEN = [REDACTED]"PROXY_TOKEN", "your-token-here") BACKENDS = [ { "url": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions", "key": os.environ.get("HERMES_DASHSCOPE_API_KEY", ""), "model": "deepseek-v4-pro" }, { "url": "https://api.openai.com/v1/chat/completions", "key": os.environ.get("OPENAI_API_KEY", ""), "model": "gpt-4o" } ] class ProxyHandler(BaseHTTPRequestHandler): def do_GET(self): self.proxy() def do_POST(self): self.proxy() def do_OPTIONS(self): self.send_response(200) self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS') self.send_header('Access-Control-Allow-Headers', '*') self.end_headers() def proxy(self): auth = self.headers.get('Authorization', '') if auth != f'Bearer {TOKEN}': self.send_response(401); self.end_headers() self.wfile.write(b'{"error":"Unauthorized"}'); return path = self.path if path == '/v1/models': self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() self.wfile.write(json.dumps({ "object": "list", "data": [{"id": b['model'], "object": "model", "owned_by": "proxy"} for b in BACKENDS if b['key']] }).encode()) return if path == '/v1/chat/completions': self.handle_chat(); return if path == '/health': self.send_response(200); self.end_headers() self.wfile.write(b'{"status":"ok"}'); return self.send_response(404); self.end_headers() self.wfile.write(b'{"error":"Not found"}') def handle_chat(self): cl = int(self.headers.get('Content-Length', 0)) body = json.loads(self.rfile.read(cl)) stream = body.get('stream', False) # Find first working backend backend = None for b in BACKENDS: if b['key']: backend = b; break if not backend: self.send_response(502); self.end_headers() self.wfile.write(b'{"error":"No backend configured"}'); return data = { "model": backend['model'], "messages": body.get('messages', []), "stream": stream, "temperature": body.get('temperature', 0.7), "max_tokens": body.get('max_tokens', 4096) } try: ctx = ssl.create_default_context() req = urllib.request.Request( backend['url'], data=json.dumps(data).encode(), method='POST' ) req.add_header('Content-Type', 'application/json') req.add_header('Authorization', f'Bearer {backend["key"]}') if stream: self.send_response(200) self.send_header('Content-Type', 'text/event-stream') self.send_header('Cache-Control', 'no-cache') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() resp = urllib.request.urlopen(req, timeout=120, context=ctx) for line_bytes in resp: self.wfile.write(line_bytes); self.wfile.flush() else: resp = urllib.request.urlopen(req, timeout=120, context=ctx) rb = resp.read() self.send_response(resp.status) self.send_header('Content-Type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() self.wfile.write(rb) except urllib.error.HTTPError as e: self.send_response(e.code) self.send_header('Content-Type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() self.wfile.write(e.read()) except Exception as e: self.send_response(500); self.end_headers() self.wfile.write(json.dumps({"error": str(e)}).encode()) def start_proxy(): print(f"\n[PROXY] http://127.0.0.1:{PORT}") print(f"[PROXY] Auth: Bearer {TOKEN[:10]}...") print(f"[PROXY] Backends: {[b['model'] for b in BACKENDS if b['key']]}") HTTPServer(('0.0.0.0', PORT), ProxyHandler).serve_forever() if __name__ == '__main__': start_proxy()