Files
weval-l99/deepseek-web-api.py
2026-04-13 12:43:21 +02:00

195 lines
6.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""
WEVIA DeepSeek Web — Navigateur headless ILLIMITÉ
Pas de token, pas d'API key — Playwright simule un navigateur
Port: 8901
"""
import json, os, time, threading, traceback
from http.server import HTTPServer, BaseHTTPRequestHandler
PORT = 8901
SESSION_DIR = '/opt/weval-l99/deepseek-session'
LOCK = threading.Lock()
browser = None
context = None
page = None
ready = False
last_error = ''
def init_browser():
global browser, context, page, ready, last_error
try:
from playwright.sync_api import sync_playwright
pw = sync_playwright().start()
browser = pw.chromium.launch(
headless=True,
args=['--no-sandbox', '--disable-gpu', '--disable-blink-features=AutomationControlled']
)
os.makedirs(SESSION_DIR, exist_ok=True)
state_file = os.path.join(SESSION_DIR, 'state.json')
ctx_args = {
'viewport': {'width': 1280, 'height': 900},
'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
}
if os.path.exists(state_file):
ctx_args['storage_state'] = state_file
context = browser.new_context(**ctx_args)
page = context.new_page()
page.goto('https://chat.deepseek.com', timeout=20000, wait_until='domcontentloaded')
page.wait_for_timeout(3000)
# Check if we're on chat page (not login)
url = page.url
title = page.title()
has_textarea = page.locator('textarea').count() > 0
if has_textarea:
ready = True
context.storage_state(path=state_file)
last_error = ''
return True
else:
ready = False
last_error = f'No textarea found. URL={url} Title={title}'
return False
except Exception as e:
last_error = str(e)
ready = False
return False
def send_message(message, mode='instant'):
global page, context, ready, last_error
if not ready or not page:
return {"error": "Browser not ready", "detail": last_error}
with LOCK:
try:
t0 = time.time()
# Click New Chat
try:
new_btn = page.locator('div:has-text("New chat")').first
if new_btn.count() > 0:
new_btn.click()
page.wait_for_timeout(1000)
except:
pass
# Toggle DeepThink if needed
if mode == 'deepthink':
try:
dt = page.locator('text=DeepThink').first
if dt.count() > 0:
dt.click()
page.wait_for_timeout(500)
except:
pass
# Toggle Search if needed
if mode == 'search':
try:
sb = page.locator('text=Search').first
if sb.count() > 0:
sb.click()
page.wait_for_timeout(500)
except:
pass
# Type and send
textarea = page.locator('textarea').first
textarea.fill(message)
page.wait_for_timeout(300)
# Press Enter or click send
textarea.press('Enter')
page.wait_for_timeout(2000)
# Wait for response (poll until stable)
last_text = ''
stable = 0
timeout = 120 if mode == 'deepthink' else 60
while time.time() - t0 < timeout:
page.wait_for_timeout(2000)
# Try to get the last response
try:
msgs = page.locator('[class*="markdown"], [class*="message-content"], [class*="prose"]')
if msgs.count() > 0:
current = msgs.last.inner_text()
if len(current) > 3 and current == last_text:
stable += 1
if stable >= 3:
break
else:
stable = 0
last_text = current
except:
pass
# Save session
try:
context.storage_state(path=os.path.join(SESSION_DIR, 'state.json'))
except:
pass
latency = int((time.time() - t0) * 1000)
return {
"content": last_text if last_text else "No response captured",
"provider": "deepseek-web-unlimited",
"mode": mode,
"latency_ms": latency,
"cost": 0,
"unlimited": True
}
except Exception as e:
last_error = str(e)
return {"error": str(e)}
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get('Content-Length', 0))
body = json.loads(self.rfile.read(length)) if length > 0 else {}
message = body.get('message', '')
mode = body.get('mode', 'instant')
if not message:
self.send_json({"error": "no message"})
return
result = send_message(message, mode)
self.send_json(result)
def do_GET(self):
if self.path == '/health':
self.send_json({"status": "ready" if ready else "not_ready", "error": last_error, "port": PORT})
elif self.path == '/init':
ok = init_browser()
self.send_json({"initialized": ok, "ready": ready, "error": last_error})
else:
self.send_json({"service": "WEVIA DeepSeek Web UNLIMITED", "modes": ["instant","deepthink","search"], "unlimited": True, "cost": 0, "no_token": True})
def send_json(self, data):
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(data, ensure_ascii=False).encode())
def log_message(self, *a): pass
if __name__ == '__main__':
print(f"WEVIA DeepSeek Web UNLIMITED :{PORT} — NO TOKEN NEEDED")
init_browser()
print(f"Ready: {ready} | Error: {last_error}")
HTTPServer(('127.0.0.1', PORT), Handler).serve_forever()