Spaces:
Sleeping
Sleeping
File size: 3,269 Bytes
3f06aeb 674a2d7 491498e ebba60d 07bf7b7 3f06aeb 674a2d7 ebba60d 674a2d7 ebba60d 674a2d7 ebba60d 674a2d7 3f06aeb 5904245 674a2d7 ebba60d 674a2d7 3f06aeb 674a2d7 491498e ebba60d 491498e 5904245 491498e 8f7852e 5904245 ebba60d 674a2d7 5904245 ebba60d 012c649 fdb04f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import os
import time
import random
import httpx
from typing import Dict
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse, StreamingResponse, Response
app = FastAPI()
BASE_URL = os.getenv("BASE_URL", "https://ollama.com")
# CLIENT API KEY (for auth)
MASTER_API_KEY = "ollama-proxy-free"
# BACKEND API KEYS (for Ollama)
API_KEYS = [
"8ca25de51e554c099962b78b7ce0c9e9.Mp5dnqctR2zzq3g-NO_M-cjW",
"dbd1d0c534964684a6d4678348ab8d30.ieDfmSYVnf0MmTjR-AIdNrW9",
"37e81a6be4104fbfbfbe2ecf557a2c10.GoIbzpHebdM9ZcHarQ9A12Cp"
]
# KEY STATUS
key_status: Dict[str, Dict] = {
k: {"fail": 0, "cooldown": 0, "status": "active"}
for k in API_KEYS
}
def auth(req: Request):
"""Validate client API key"""
client_key = req.headers.get("Authorization", "").replace("Bearer ", "")
if client_key != MASTER_API_KEY:
raise HTTPException(401, "Unauthorized")
def pick_key():
now = time.time()
valid = [k for k, v in key_status.items()
if v["status"] != "dead" and v["cooldown"] < now]
if valid:
return random.choice(valid)
# Reset if all failed
for k in key_status:
key_status[k]["status"] = "active"
key_status[k]["fail"] = 0
return random.choice(API_KEYS)
def mark_fail(key: str):
key_status[key]["fail"] += 1
if key_status[key]["fail"] >= 3:
key_status[key]["cooldown"] = time.time() + 60
def mark_ok(key: str):
key_status[key]["fail"] = 0
key_status[key]["status"] = "active"
@app.get("/")
def root():
active = sum(1 for v in key_status.values() if v["status"] == "active")
return {
"status": "ok",
"mode": "openai-proxy",
"keys_total": len(API_KEYS),
"keys_active": active
}
@app.api_route("/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy(req: Request, path: str):
# Auth first
auth(req)
target_url = f"{BASE_URL}/v1/{path}"
body = await req.body()
headers = dict(req.headers)
headers.pop("host", None)
headers.pop("content-length", None)
# Try each key
tried = set()
for _ in range(len(API_KEYS)):
key = pick_key()
if key in tried:
continue
tried.add(key)
headers["Authorization"] = f"Bearer {key}"
try:
async with httpx.AsyncClient(timeout=60) as client:
resp = await client.request(
method=req.method,
url=target_url,
headers=headers,
content=body,
params=req.query_params
)
if resp.status_code < 400:
mark_ok(key)
return Response(
content=resp.content,
status_code=resp.status_code,
headers=dict(resp.headers)
)
mark_fail(key)
continue
except Exception as e:
mark_fail(key)
continue
return JSONResponse({"error": "all keys failed"}, status_code=500)
# rebuild
# Testing build
|