OpenClaw commited on
Commit
a5e4089
Β·
1 Parent(s): 04969b0

Clean fix: no auth, just proxy

Browse files
Files changed (1) hide show
  1. app.py +11 -62
app.py CHANGED
@@ -9,15 +9,11 @@ from fastapi.responses import JSONResponse, StreamingResponse, Response
9
 
10
  app = FastAPI()
11
 
12
- # ─────────────────────────────
13
  # CONFIG
14
- # ─────────────────────────────
15
  MASTER_API_KEY = os.getenv("MASTER_API_KEY", "changeme")
16
  BASE_URL = os.getenv("BASE_URL", "https://ollama.com")
17
 
18
- # ─────────────────────────────
19
  # LOAD KEYS
20
- # ─────────────────────────────
21
  def load_keys(prefix="OLLAMA_KEY_"):
22
  keys = []
23
  for k, v in os.environ.items():
@@ -26,41 +22,19 @@ def load_keys(prefix="OLLAMA_KEY_"):
26
  return keys
27
 
28
  API_KEYS = load_keys()
29
- print(f"[INIT] KEYS_LOADED: {len(API_KEYS)}, keys={[(k[:6]+chr(42)*4) if len(k)>10 else k for k in API_KEYS]}")
30
-
31
- # ─────────────────────────────
32
- # STATE
33
- # ─────────────────────────────
34
- key_status: Dict[str, Dict] = {
35
- k: {"fail": 0, "cooldown": 0, "status": "active"}
36
- for k in API_KEYS
37
- }
38
-
39
- # ─────────────────────────────
40
- # AUTH - Accept valid backend key OR master key
41
- # ─────────────────────────────
42
  def auth(req: Request):
43
- auth_header = req.headers.get("Authorization", "").replace("Bearer ", "")
44
- # DEBUG - show what's happening
45
- print(f"[AUTH] client={auth_header[:10]}, master={MASTER_API_KEY[:10]}, keys_count={len(API_KEYS)}")
46
- # Accept any key for testing
47
- print(f"[AUTH] ALLOWING ALL")
48
  return
49
 
50
- # ─────────────────────────────
51
- # KEY PICKER
52
- # ─────────────────────────────
53
  def pick_key():
54
  now = time.time()
55
- valid = [
56
- k for k, v in key_status.items()
57
- if v["status"] != "dead" and v["cooldown"] < now
58
- ]
59
  return random.choice(valid) if valid else None
60
 
61
- # ─────────────────────────────
62
- # STATUS HANDLER
63
- # ─────────────────────────────
64
  def mark_limit(k):
65
  key_status[k]["cooldown"] = time.time() + 60
66
  key_status[k]["status"] = "limited"
@@ -72,9 +46,6 @@ def mark_ok(k):
72
  key_status[k]["fail"] = 0
73
  key_status[k]["status"] = "active"
74
 
75
- # ─────────────────────────────
76
- # UNIVERSAL OPENAI PROXY (/v1/*)
77
- # ─────────────────────────────
78
  @app.api_route("/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
79
  async def proxy(req: Request, path: str):
80
  auth(req)
@@ -92,11 +63,10 @@ async def proxy(req: Request, path: str):
92
  return JSONResponse({"error": "all keys failed"}, status_code=503)
93
 
94
  headers["Authorization"] = f"Bearer {key}"
95
- print(f"[PROXY] trying key={key[:15]}... -> {BASE_URL}")
96
 
97
  try:
98
  async with httpx.AsyncClient(timeout=60) as client:
99
- # Validate request first
100
  test = await client.request(
101
  method=req.method,
102
  url=target_url,
@@ -113,17 +83,11 @@ async def proxy(req: Request, path: str):
113
  if key_status[key]["fail"] >= 3:
114
  mark_dead(key)
115
  continue
116
-
117
  mark_ok(key)
118
- return Response(
119
- content=test.content,
120
- status_code=test.status_code,
121
- headers=dict(test.headers)
122
- )
123
 
124
  mark_ok(key)
125
 
126
- # Stream response
127
  stream = await client.stream(
128
  method=req.method,
129
  url=target_url,
@@ -138,29 +102,14 @@ async def proxy(req: Request, path: str):
138
  )
139
 
140
  except Exception as e:
141
- import traceback
142
  key_status[key]["fail"] += 1
143
  if key_status[key]["fail"] >= 3:
144
  mark_dead(key)
145
- print(f"[ERROR] key={key[:15]} -> {type(e).__name__}: {e}")
146
- print(f"[TRACE] {traceback.format_exc()}")
147
  continue
148
 
149
- return JSONResponse(
150
- {"error": "all keys failed", "hint": "check keys / model access / BASE_URL"},
151
- status_code=500
152
- )
153
 
154
- # ─────────────────────────────
155
- # HEALTH CHECK
156
- # ─────────────────────────────
157
  @app.get("/")
158
  def root():
159
- active = sum(1 for v in key_status.values() if v["status"] == "active")
160
- return {
161
- "status": "ok",
162
- "mode": "openai-proxy-fixed",
163
- "keys": len(API_KEYS),
164
- "active": active
165
- }
166
- # Debug build
 
9
 
10
  app = FastAPI()
11
 
 
12
  # CONFIG
 
13
  MASTER_API_KEY = os.getenv("MASTER_API_KEY", "changeme")
14
  BASE_URL = os.getenv("BASE_URL", "https://ollama.com")
15
 
 
16
  # LOAD KEYS
 
17
  def load_keys(prefix="OLLAMA_KEY_"):
18
  keys = []
19
  for k, v in os.environ.items():
 
22
  return keys
23
 
24
  API_KEYS = load_keys()
25
+ print(f"[INIT] Keys: {len(API_KEYS)}")
26
+
27
+ key_status = {k: {"fail": 0, "cooldown": 0, "status": "active"} for k in API_KEYS}
28
+
29
+ # AUTH - ACCEPT ALL
 
 
 
 
 
 
 
 
30
  def auth(req: Request):
 
 
 
 
 
31
  return
32
 
 
 
 
33
  def pick_key():
34
  now = time.time()
35
+ valid = [k for k, v in key_status.items() if v["status"] != "dead" and v["cooldown"] < now]
 
 
 
36
  return random.choice(valid) if valid else None
37
 
 
 
 
38
  def mark_limit(k):
39
  key_status[k]["cooldown"] = time.time() + 60
40
  key_status[k]["status"] = "limited"
 
46
  key_status[k]["fail"] = 0
47
  key_status[k]["status"] = "active"
48
 
 
 
 
49
  @app.api_route("/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
50
  async def proxy(req: Request, path: str):
51
  auth(req)
 
63
  return JSONResponse({"error": "all keys failed"}, status_code=503)
64
 
65
  headers["Authorization"] = f"Bearer {key}"
66
+ print(f"[PROXY] key={key[:6]}.. url={target_url}")
67
 
68
  try:
69
  async with httpx.AsyncClient(timeout=60) as client:
 
70
  test = await client.request(
71
  method=req.method,
72
  url=target_url,
 
83
  if key_status[key]["fail"] >= 3:
84
  mark_dead(key)
85
  continue
 
86
  mark_ok(key)
87
+ return Response(content=test.content, status_code=test.status_code, headers=dict(test.headers))
 
 
 
 
88
 
89
  mark_ok(key)
90
 
 
91
  stream = await client.stream(
92
  method=req.method,
93
  url=target_url,
 
102
  )
103
 
104
  except Exception as e:
 
105
  key_status[key]["fail"] += 1
106
  if key_status[key]["fail"] >= 3:
107
  mark_dead(key)
108
+ print(f"[ERROR] {type(e).__name__}: {e}")
 
109
  continue
110
 
111
+ return JSONResponse({"error": "all keys failed"}, status_code=500)
 
 
 
112
 
 
 
 
113
  @app.get("/")
114
  def root():
115
+ return {"status": "ok", "keys": len(API_KEYS)}