dolor3v-gateway / app.py
Daviddolor
feat: groq + key system
ca4923a
Raw
History Blame Contribute Delete
6.32 kB
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)