from flask import Flask, request, jsonify, Response import urllib.request, urllib.error, json, os, time, secrets app = Flask(__name__) OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY", "") ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY", "") GROQ_API_KEY = os.environ.get("GROQ_API_KEY", "") GATEWAY_MASTER_KEY = os.environ.get("GATEWAY_MASTER_KEY", "dolordprince-master") CREATOR = "dolordprince" KEYS_FILE = "/tmp/dolor3v_keys.json" def load_keys(): try: if os.path.exists(KEYS_FILE): return json.load(open(KEYS_FILE)) except: pass return {"d3v-master-dolordprince-2026":{"name":"dolordprince-master","owner":"dolordprince","created":"2026-01-01","expires":None,"requests":0,"active":True,"tier":"unlimited"}} def save_keys(keys): try: json.dump(keys, open(KEYS_FILE,"w"), indent=2) except: pass KEYS = load_keys() def validate_key(api_key): if not api_key: return False, "No API key provided" api_key = api_key.replace("Bearer ","").strip() if api_key not in KEYS: return False, "Invalid API key" kd = KEYS[api_key] if not kd.get("active",True): return False, "API key disabled" exp = kd.get("expires") if exp and time.time() > exp: return False, "API key expired" KEYS[api_key]["requests"] = KEYS[api_key].get("requests",0)+1 save_keys(KEYS) return True, kd def get_key(): auth = request.headers.get("Authorization","") if auth: return auth.replace("Bearer ","").strip() return request.headers.get("X-API-Key","") def cors(resp): resp.headers["Access-Control-Allow-Origin"] = "*" resp.headers["Access-Control-Allow-Headers"] = "*" resp.headers["Access-Control-Allow-Methods"] = "GET,POST,OPTIONS,DELETE" return resp def err(msg, code=401): r = jsonify({"error":{"message":msg,"code":code}}) return cors(r), code @app.route("/", methods=["GET"]) def root(): return cors(jsonify({"status":"ok","name":"dolor3v-gateway","creator":CREATOR,"version":"2.0"})) @app.route("/health", methods=["GET"]) def health(): return cors(jsonify({"status":"ok","gateway":"dolor3v-gateway","creator":CREATOR,"providers":{"groq":bool(GROQ_API_KEY),"openrouter":bool(OPENROUTER_API_KEY),"anthropic":bool(ANTHROPIC_API_KEY)}})) @app.route("/v1/chat/completions", methods=["POST","OPTIONS"]) def chat(): if request.method == "OPTIONS": return cors(jsonify({})) valid, result = validate_key(get_key()) if not valid: return err(result) body = request.get_json(force=True, silent=True) or {} model = body.get("model","groq/llama-3.3-70b-versatile") if model.startswith("groq/"): body["model"] = model[5:]; status,data = call_groq(body) elif model.startswith("openrouter/"): body["model"] = model[11:]; status,data = call_openrouter(body) elif model.startswith("anthropic/"): body["model"] = model[10:]; status,data = call_anthropic(body) else: status,data = call_groq(body) if status != 200: status,data = call_openrouter(body) return cors(Response(data, status=status, mimetype="application/json")) @app.route("/keys/create", methods=["POST"]) def create_key(): if request.headers.get("X-Master-Key","") != GATEWAY_MASTER_KEY: return err("Master key required",403) body = request.get_json(force=True, silent=True) or {} raw = f"d3v-{secrets.token_hex(16)}" ed = body.get("expires_days") KEYS[raw] = {"name":body.get("name","user"),"owner":body.get("owner","unknown"),"created":time.strftime("%Y-%m-%d"),"expires":time.time()+(ed*86400) if ed else None,"requests":0,"active":True,"tier":body.get("tier","standard")} save_keys(KEYS) return cors(jsonify({"key":raw,"data":KEYS[raw]})) @app.route("/keys", methods=["GET"]) def list_keys(): if request.headers.get("X-Master-Key","") != GATEWAY_MASTER_KEY: return err("Master key required",403) return cors(jsonify({"keys":{k:{**v,"key":k} for k,v in KEYS.items()},"total":len(KEYS)})) def call_groq(body): data = json.dumps(body).encode() req = urllib.request.Request("https://api.groq.com/openai/v1/chat/completions",data=data, headers={"Content-Type":"application/json","Authorization":f"Bearer {GROQ_API_KEY}"},method="POST") try: with urllib.request.urlopen(req,timeout=60) as r: return r.status,r.read() except urllib.error.HTTPError as e: return e.code,e.read() except Exception as e: return 500,json.dumps({"error":{"message":str(e)}}).encode() def call_openrouter(body): data = json.dumps(body).encode() req = urllib.request.Request("https://openrouter.ai/api/v1/chat/completions",data=data, headers={"Content-Type":"application/json","Authorization":f"Bearer {OPENROUTER_API_KEY}","HTTP-Referer":"https://dolor3v.hf.space","X-Title":"dolor3v-gateway"},method="POST") try: with urllib.request.urlopen(req,timeout=60) as r: return r.status,r.read() except urllib.error.HTTPError as e: return e.code,e.read() except Exception as e: return 500,json.dumps({"error":{"message":str(e)}}).encode() def call_anthropic(body): messages = body.get("messages",[]); system=None; filtered=[] for m in messages: if m.get("role")=="system": system=m.get("content") else: filtered.append(m) ab={"model":body.get("model","claude-haiku-4-5"),"max_tokens":body.get("max_tokens",1024),"messages":filtered} if system: ab["system"]=system data=json.dumps(ab).encode() req=urllib.request.Request("https://api.anthropic.com/v1/messages",data=data, headers={"Content-Type":"application/json","x-api-key":ANTHROPIC_API_KEY,"anthropic-version":"2023-06-01"},method="POST") try: with urllib.request.urlopen(req,timeout=60) as r: raw=json.loads(r.read()) return 200,json.dumps({"id":raw.get("id"),"object":"chat.completion","model":raw.get("model"),"choices":[{"index":0,"message":{"role":"assistant","content":raw["content"][0]["text"] if raw.get("content") else ""},"finish_reason":raw.get("stop_reason","stop")}],"usage":raw.get("usage",{})}).encode() except urllib.error.HTTPError as e: return e.code,e.read() except Exception as e: return 500,json.dumps({"error":{"message":str(e)}}).encode() if __name__ == "__main__": app.run(host="0.0.0.0", port=7860, debug=False)