""" DeepSeek Web API Proxy Server (OpenAI-Compatible Gateway) Hugging Face Space Edition Version: 1.2.1 Description: Zero-dependency proxy mapping OpenAI completions to DeepSeek Web API """ import http.server import socketserver import json import urllib.request import urllib.error import sys import uuid import struct import binascii import base64 import time import threading import traceback import os from collections import defaultdict sys.stdout.reconfigure(encoding='utf-8') # --- CONFIGURATION --- PORT = int(os.environ.get("PORT", "7860")) HOST = "0.0.0.0" # Load token from env or file def _load_token(): tok = os.environ.get("DEEPSEEK_TOKEN", "").strip() if tok: return tok for path in ["token.txt", "/app/token.txt"]: try: with open(path, "r") as f: tok = f.read().strip() if tok: return tok except FileNotFoundError: pass return "" USER_TOKEN = _load_token() if not USER_TOKEN: print("WARNING: DEEPSEEK_TOKEN not set! Set it in HF Secrets.") print("Token format: oxMs/... (from browser at chat.deepseek.com)") # --- SESSION MANAGEMENT --- ACTIVE_SESSIONS = defaultdict(lambda: {"session_id": None, "message_history": []}) # Terminal Colors (disabled if no TTY) class Colors: if sys.stdout.isatty(): HEADER = '\033[95m'; BLUE = '\033[94m'; CYAN = '\033[96m'; GREEN = '\033[92m' WARNING = '\033[93m'; FAIL = '\033[91m'; ENDC = '\033[0m'; BOLD = '\033[1m' else: HEADER = BLUE = CYAN = GREEN = WARNING = FAIL = ENDC = BOLD = '' # --- HIGH PERFORMANCE DEEPSEEK POW SOLVER --- RC = [ 0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000, 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A, 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A, 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, ] def rotl64(v, k): return ((v << k) | (v >> (64 - k))) & 0xffffffffffffffff def keccakF23(s): a0, a1, a2, a3, a4 = s[0], s[1], s[2], s[3], s[4] a5, a6, a7, a8, a9 = s[5], s[6], s[7], s[8], s[9] a10, a11, a12, a13, a14 = s[10], s[11], s[12], s[13], s[14] a15, a16, a17, a18, a19 = s[15], s[16], s[17], s[18], s[19] a20, a21, a22, a23, a24 = s[20], s[21], s[22], s[23], s[24] for r in range(1, 24): c0 = a0 ^ a5 ^ a10 ^ a15 ^ a20 c1 = a1 ^ a6 ^ a11 ^ a16 ^ a21 c2 = a2 ^ a7 ^ a12 ^ a17 ^ a22 c3 = a3 ^ a8 ^ a13 ^ a18 ^ a23 c4 = a4 ^ a9 ^ a14 ^ a19 ^ a24 d0 = c4 ^ rotl64(c1, 1) d1 = c0 ^ rotl64(c2, 1) d2 = c1 ^ rotl64(c3, 1) d3 = c2 ^ rotl64(c4, 1) d4 = c3 ^ rotl64(c0, 1) a0 ^= d0; a5 ^= d0; a10 ^= d0; a15 ^= d0; a20 ^= d0 a1 ^= d1; a6 ^= d1; a11 ^= d1; a16 ^= d1; a21 ^= d1 a2 ^= d2; a7 ^= d2; a12 ^= d2; a17 ^= d2; a22 ^= d2 a3 ^= d3; a8 ^= d3; a13 ^= d3; a18 ^= d3; a23 ^= d3 a4 ^= d4; a9 ^= d4; a14 ^= d4; a19 ^= d4; a24 ^= d4 b0 = a0 b10 = rotl64(a1, 1) b20 = rotl64(a2, 62) b5 = rotl64(a3, 28) b15 = rotl64(a4, 27) b16 = rotl64(a5, 36) b1 = rotl64(a6, 44) b11 = rotl64(a7, 6) b21 = rotl64(a8, 55) b6 = rotl64(a9, 20) b7 = rotl64(a10, 3) b17 = rotl64(a11, 10) b2 = rotl64(a12, 43) b12 = rotl64(a13, 25) b22 = rotl64(a14, 39) b23 = rotl64(a15, 41) b8 = rotl64(a16, 45) b18 = rotl64(a17, 15) b3 = rotl64(a18, 21) b13 = rotl64(a19, 8) b14 = rotl64(a20, 18) b24 = rotl64(a21, 2) b9 = rotl64(a22, 61) b19 = rotl64(a23, 56) b4 = rotl64(a24, 14) a0 = b0 ^ ((~b1) & b2) a1 = b1 ^ ((~b2) & b3) a2 = b2 ^ ((~b3) & b4) a3 = b3 ^ ((~b4) & b0) a4 = b4 ^ ((~b0) & b1) a5 = b5 ^ ((~b6) & b7) a6 = b6 ^ ((~b7) & b8) a7 = b7 ^ ((~b8) & b9) a8 = b8 ^ ((~b9) & b5) a9 = b9 ^ ((~b5) & b6) a10 = b10 ^ ((~b11) & b12) a11 = b11 ^ ((~b12) & b13) a12 = b12 ^ ((~b13) & b14) a13 = b13 ^ ((~b14) & b10) a14 = b14 ^ ((~b10) & b11) a15 = b15 ^ ((~b16) & b17) a16 = b16 ^ ((~b17) & b18) a17 = b17 ^ ((~b18) & b19) a18 = b18 ^ ((~b19) & b15) a19 = b19 ^ ((~b15) & b16) a20 = b20 ^ ((~b21) & b22) a21 = b21 ^ ((~b22) & b23) a22 = b22 ^ ((~b23) & b24) a23 = b23 ^ ((~b24) & b20) a24 = b24 ^ ((~b20) & b21) a0 &= 0xffffffffffffffff; a1 &= 0xffffffffffffffff; a2 &= 0xffffffffffffffff; a3 &= 0xffffffffffffffff; a4 &= 0xffffffffffffffff a5 &= 0xffffffffffffffff; a6 &= 0xffffffffffffffff; a7 &= 0xffffffffffffffff; a8 &= 0xffffffffffffffff; a9 &= 0xffffffffffffffff a10 &= 0xffffffffffffffff; a11 &= 0xffffffffffffffff; a12 &= 0xffffffffffffffff; a13 &= 0xffffffffffffffff; a14 &= 0xffffffffffffffff a15 &= 0xffffffffffffffff; a16 &= 0xffffffffffffffff; a17 &= 0xffffffffffffffff; a18 &= 0xffffffffffffffff; a19 &= 0xffffffffffffffff a20 &= 0xffffffffffffffff; a21 &= 0xffffffffffffffff; a22 &= 0xffffffffffffffff; a23 &= 0xffffffffffffffff; a24 &= 0xffffffffffffffff a0 ^= RC[r] s[0], s[1], s[2], s[3], s[4] = a0, a1, a2, a3, a4 s[5], s[6], s[7], s[8], s[9] = a5, a6, a7, a8, a9 s[10], s[11], s[12], s[13], s[14] = a10, a11, a12, a13, a14 s[15], s[16], s[17], s[18], s[19] = a15, a16, a17, a18, a19 s[20], s[21], s[22], s[23], s[24] = a20, a21, a22, a23, a24 def solve_pow(challenge_hex, salt, expire_at, difficulty): target = binascii.unhexlify(challenge_hex) t0, t1, t2, t3 = struct.unpack(" Secrets.") return content_length = int(self.headers.get('Content-Length', 0)) post_data = self.rfile.read(content_length) try: req_body = json.loads(post_data.decode('utf-8')) except Exception as e: self.send_error_response(400, f"Invalid JSON: {e}") return messages = req_body.get("messages", []) stream = req_body.get("stream", False) model = req_body.get("model", "deepseek-chat") conversation_id = req_body.get("conversation_id", "default") thinking_enabled = (model == "deepseek-reasoner") session_data = ACTIVE_SESSIONS[conversation_id] prompt = "" for msg in messages: role = msg.get("role", "user") content = msg.get("content", "") if isinstance(content, list): text_parts = [] for part in content: if isinstance(part, dict): pt = part.get("type", "text") if pt == "text": text_parts.append(part.get("text", "")) elif pt == "file": text_parts.append(f"\n```{part.get('name','file')}\n{part.get('content','')}\n```\n") elif pt == "image_url": text_parts.append("[Image: not supported]") elif isinstance(part, str): text_parts.append(part) content = "".join(text_parts) if role in ("system", "user", "assistant"): prompt += f"{content}\n\n" prompt = prompt.strip() print(f"{Colors.BLUE}💬 Request | Model: {model} | Stream: {stream}{Colors.ENDC}") try: if session_data["session_id"] is None: session_id = create_chat_session() session_data["session_id"] = session_id print(f"{Colors.GREEN}🆕 Session: {session_id[:16]}...{Colors.ENDC}") else: session_id = session_data["session_id"] print(f"{Colors.CYAN}♻️ Reusing session{Colors.ENDC}") pow_header = get_pow_header() except Exception as e: traceback.print_exc() self.send_error_response(500, f"Upstream setup error: {e}") return ds_headers = { "Authorization": f"Bearer {USER_TOKEN}", "Content-Type": "application/json", "Accept": "text/event-stream", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Referer": "https://chat.deepseek.com/", "Origin": "https://chat.deepseek.com", "x-client-platform": "web", "x-app-version": "20241129.1", "x-ds-pow-response": pow_header } ds_payload = json.dumps({ "chat_session_id": session_id, "prompt": prompt, "parent_message_id": None, "ref": "web", "ref_file_ids": [], "search_enabled": False, "thinking_enabled": thinking_enabled }).encode('utf-8') ds_req = urllib.request.Request( "https://chat.deepseek.com/api/v0/chat/completion", data=ds_payload, headers=ds_headers, method="POST" ) try: response = urllib.request.urlopen(ds_req, timeout=90) first_line = response.readline().decode('utf-8').strip() if "INVALID_POW_RESPONSE" in first_line or "40301" in first_line: response.close() with POW_CACHE_LOCK: POW_CACHE["header"] = None POW_CACHE["expires"] = 0 pow_header = get_pow_header() ds_headers["x-ds-pow-response"] = pow_header ds_req = urllib.request.Request( "https://chat.deepseek.com/api/v0/chat/completion", data=ds_payload, headers=ds_headers, method="POST" ) response = urllib.request.urlopen(ds_req, timeout=90) print(f"{Colors.GREEN}🔄 Retried with fresh PoW{Colors.ENDC}") else: class ResponseWithFirstLine: def __init__(self, first_line, response): self.first_line = first_line.encode('utf-8') + b'\n' self.response = response self.first_yielded = False def __iter__(self): if not self.first_yielded: yield self.first_line self.first_yielded = True for line in self.response: yield line def close(self): self.response.close() response = ResponseWithFirstLine(first_line, response) except urllib.error.HTTPError as e: err_body = e.read().decode('utf-8') if e.fp else "" print(f"{Colors.FAIL}❌ Upstream HTTP {e.code}: {err_body}{Colors.ENDC}") self.send_error_response(e.code, f"Upstream error: {err_body}") return except Exception as e: traceback.print_exc() self.send_error_response(503, f"Failed to connect: {e}") return self.send_response(200) self.send_cors_headers() if stream: self.send_header('Content-Type', 'text/event-stream') self.send_header('Cache-Control', 'no-cache') self.send_header('Connection', 'keep-alive') self.end_headers() self.stream_response(response, model) else: self.send_header('Content-Type', 'application/json') self.end_headers() self.blocking_response(response, model) def stream_response(self, response, model): created_time = int(time.time()) req_id = f"chatcmpl-{uuid.uuid4()}" is_thinking = (model == "deepseek-reasoner") try: chunk_count = 0 for raw_line in response: line = raw_line.decode('utf-8').strip() if not line: continue if line.startswith("event:"): event_name = line[6:].strip() if event_name in ("close", "finish"): break continue if not line.startswith("data:"): continue data_str = line[5:].strip() if data_str == "[DONE]": break try: ds_chunk = json.loads(data_str) except: continue p_val = ds_chunk.get("p") v_val = ds_chunk.get("v") if p_val in ("response/accumulated_token_usage", "response/status"): if p_val == "response/status" and v_val == "FINISHED": break continue if p_val == "response/thinking_elapsed_secs": is_thinking = False continue elif p_val == "response/content": is_thinking = False if isinstance(v_val, str): self.send_openai_chunk(req_id, created_time, model, v_val, None, None) continue if isinstance(v_val, str): chunk_count += 1 if is_thinking: self.send_openai_chunk(req_id, created_time, model, None, v_val, None) else: self.send_openai_chunk(req_id, created_time, model, v_val, None, None) self.send_openai_chunk(req_id, created_time, model, None, None, "stop") self.wfile.write(b"data: [DONE]\n\n") self.wfile.flush() print(f"{Colors.GREEN}>> Stream done. {chunk_count} chunks{Colors.ENDC}") except Exception as e: print(f"{Colors.FAIL}>> Stream error: {e}{Colors.ENDC}") finally: response.close() def send_openai_chunk(self, req_id, created_time, model, content, reasoning_content, finish_reason): delta = {} if content is not None: delta["content"] = content if reasoning_content is not None: delta["reasoning_content"] = reasoning_content chunk_payload = { "id": req_id, "object": "chat.completion.chunk", "created": created_time, "model": model, "choices": [{"index": 0, "delta": delta, "finish_reason": finish_reason}] } sse_str = f"data: {json.dumps(chunk_payload)}\n\n" self.wfile.write(sse_str.encode('utf-8')) self.wfile.flush() def blocking_response(self, response, model): created_time = int(time.time()) req_id = f"chatcmpl-{uuid.uuid4()}" full_content = "" full_reasoning = "" is_thinking = (model == "deepseek-reasoner") try: for raw_line in response: line = raw_line.decode('utf-8').strip() if not line: continue if line.startswith("event:"): event_name = line[6:].strip() if event_name in ("close", "finish"): break continue if not line.startswith("data:"): continue data_str = line[5:].strip() if data_str == "[DONE]": break try: ds_chunk = json.loads(data_str) except: continue p_val = ds_chunk.get("p") v_val = ds_chunk.get("v") if p_val in ("response/accumulated_token_usage", "response/status"): if p_val == "response/status" and v_val == "FINISHED": break continue if p_val == "response/thinking_elapsed_secs": is_thinking = False continue elif p_val == "response/content": is_thinking = False if isinstance(v_val, str): full_content += v_val continue if isinstance(v_val, str): if is_thinking: full_reasoning += v_val else: full_content += v_val print(f"{Colors.GREEN}✅ Blocking response: {len(full_content)} chars content{Colors.ENDC}") res_payload = { "id": req_id, "object": "chat.completion", "created": created_time, "model": model, "choices": [{ "index": 1, "message": { "role": "assistant", "content": full_content, "reasoning_content": full_reasoning if full_reasoning else None }, "finish_reason": "stop" }], "usage": { "prompt_tokens": len(full_content) // 4 + 10, "completion_tokens": len(full_content) // 4, "total_tokens": (len(full_content) // 4) * 2 + 10 } } self.wfile.write(json.dumps(res_payload).encode('utf-8')) except Exception as e: traceback.print_exc() self.send_error_response(500, f"Error gathering response: {e}") finally: response.close() def send_error_response(self, code, message): self.send_response(code) self.send_cors_headers() self.send_header('Content-Type', 'application/json') self.end_headers() err_payload = {"error": {"message": message, "type": "api_error", "code": code}} self.wfile.write(json.dumps(err_payload).encode('utf-8')) # --- SERVER START --- def start_server(): print(f"\n{Colors.HEADER}{Colors.BOLD}==================================================={Colors.ENDC}") print(f"{Colors.CYAN}{Colors.BOLD} 🚀 DEEPSEEK PROXY - HUGGING FACE SPACE EDITION 🚀{Colors.ENDC}") print(f"{Colors.HEADER}{Colors.BOLD}==================================================={Colors.ENDC}") print(f"📡 Endpoint: {Colors.BOLD}http://{HOST}:{PORT}/v1{Colors.ENDC}") print(f"🔑 Token: {Colors.WARNING}{'✅ Configured' if USER_TOKEN else '❌ NOT SET'}{Colors.ENDC}") print(f"🧠 Models: {Colors.GREEN}deepseek-chat, deepseek-reasoner{Colors.ENDC}") print(f"🛡️ PoW Engine: {Colors.GREEN}Keccak solver (cached 5 min){Colors.ENDC}") print(f"📊 Health: {Colors.BOLD}GET /health{Colors.ENDC}") print(f"{Colors.HEADER}==================================================={Colors.ENDC}\n") server_address = (HOST, PORT) try: with ThreadedHTTPServer(server_address, OpenAICompatibleHandler) as httpd: print(f"{Colors.GREEN}🔥 Server running on {HOST}:{PORT}{Colors.ENDC}") httpd.serve_forever() except KeyboardInterrupt: print(f"\n{Colors.WARNING}⚠️ Shutting down...{Colors.ENDC}") except Exception as e: print(f"\n{Colors.FAIL}❌ Server error: {e}{Colors.ENDC}") sys.exit(1) if __name__ == "__main__": start_server()