Spaces:
Paused
Paused
Upload proxy_handler.py
Browse files- proxy_handler.py +42 -38
proxy_handler.py
CHANGED
|
@@ -155,10 +155,45 @@ class ProxyHandler:
|
|
| 155 |
}
|
| 156 |
return body, headers, cookie
|
| 157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
# Streaming response
|
| 159 |
|
| 160 |
async def stream_proxy_response(self, request: ChatCompletionRequest) -> AsyncGenerator[str, None]:
|
| 161 |
client = None
|
|
|
|
| 162 |
try:
|
| 163 |
client = httpx.AsyncClient(
|
| 164 |
timeout=httpx.Timeout(60.0, read=300.0),
|
|
@@ -261,18 +296,21 @@ class ProxyHandler:
|
|
| 261 |
|
| 262 |
except httpx.RequestError as e:
|
| 263 |
logger.error(f"Request error: {e}")
|
| 264 |
-
if
|
| 265 |
await cookie_manager.mark_cookie_invalid(cookie)
|
| 266 |
-
|
|
|
|
| 267 |
except Exception as e:
|
| 268 |
logger.error(f"Unexpected error: {e}")
|
| 269 |
-
|
|
|
|
| 270 |
finally:
|
| 271 |
if client:
|
| 272 |
await client.aclose()
|
| 273 |
|
| 274 |
async def non_stream_proxy_response(self, request: ChatCompletionRequest):
|
| 275 |
client = None
|
|
|
|
| 276 |
try:
|
| 277 |
client = httpx.AsyncClient(
|
| 278 |
timeout=httpx.Timeout(60.0, read=300.0),
|
|
@@ -340,7 +378,7 @@ class ProxyHandler:
|
|
| 340 |
|
| 341 |
except httpx.RequestError as e:
|
| 342 |
logger.error(f"Request error: {e}")
|
| 343 |
-
if
|
| 344 |
await cookie_manager.mark_cookie_invalid(cookie)
|
| 345 |
raise HTTPException(status_code=502, detail="Upstream connection error")
|
| 346 |
except Exception as e:
|
|
@@ -350,40 +388,6 @@ class ProxyHandler:
|
|
| 350 |
if client:
|
| 351 |
await client.aclose()
|
| 352 |
|
| 353 |
-
# Utilities
|
| 354 |
-
|
| 355 |
-
def _mk_chunk(self, cid: str, model: str, content: str) -> str:
|
| 356 |
-
"""Create a chunk and return with data: prefix"""
|
| 357 |
-
chunk = {
|
| 358 |
-
"id": cid,
|
| 359 |
-
"object": "chat.completion.chunk",
|
| 360 |
-
"created": int(time.time()),
|
| 361 |
-
"model": model,
|
| 362 |
-
"choices": [{
|
| 363 |
-
"index": 0,
|
| 364 |
-
"delta": {"content": content},
|
| 365 |
-
"finish_reason": None
|
| 366 |
-
}]
|
| 367 |
-
}
|
| 368 |
-
return f"data: {json.dumps(chunk)}\n\n"
|
| 369 |
-
|
| 370 |
-
def _error_chunks(self, model: str, msg: str):
|
| 371 |
-
"""Generate error output (generator)"""
|
| 372 |
-
cid = f"chatcmpl-{uuid.uuid4().hex[:29]}"
|
| 373 |
-
err = {
|
| 374 |
-
"id": cid,
|
| 375 |
-
"object": "chat.completion.chunk",
|
| 376 |
-
"created": int(time.time()),
|
| 377 |
-
"model": model,
|
| 378 |
-
"choices": [{
|
| 379 |
-
"index": 0,
|
| 380 |
-
"delta": {"content": msg},
|
| 381 |
-
"finish_reason": "stop"
|
| 382 |
-
}]
|
| 383 |
-
}
|
| 384 |
-
yield f"data: {json.dumps(err)}\n\n"
|
| 385 |
-
yield "data: [DONE]\n\n"
|
| 386 |
-
|
| 387 |
# FastAPI entry point
|
| 388 |
|
| 389 |
async def handle_chat_completion(self, request: ChatCompletionRequest):
|
|
|
|
| 155 |
}
|
| 156 |
return body, headers, cookie
|
| 157 |
|
| 158 |
+
# Utilities
|
| 159 |
+
|
| 160 |
+
def _mk_chunk(self, cid: str, model: str, content: str) -> str:
|
| 161 |
+
"""Create a chunk and return with data: prefix"""
|
| 162 |
+
chunk = {
|
| 163 |
+
"id": cid,
|
| 164 |
+
"object": "chat.completion.chunk",
|
| 165 |
+
"created": int(time.time()),
|
| 166 |
+
"model": model,
|
| 167 |
+
"choices": [{
|
| 168 |
+
"index": 0,
|
| 169 |
+
"delta": {"content": content},
|
| 170 |
+
"finish_reason": None
|
| 171 |
+
}]
|
| 172 |
+
}
|
| 173 |
+
return f"data: {json.dumps(chunk)}\n\n"
|
| 174 |
+
|
| 175 |
+
async def _error_chunks_async(self, model: str, msg: str):
|
| 176 |
+
"""Generate error output (async generator)"""
|
| 177 |
+
cid = f"chatcmpl-{uuid.uuid4().hex[:29]}"
|
| 178 |
+
err = {
|
| 179 |
+
"id": cid,
|
| 180 |
+
"object": "chat.completion.chunk",
|
| 181 |
+
"created": int(time.time()),
|
| 182 |
+
"model": model,
|
| 183 |
+
"choices": [{
|
| 184 |
+
"index": 0,
|
| 185 |
+
"delta": {"content": msg},
|
| 186 |
+
"finish_reason": "stop"
|
| 187 |
+
}]
|
| 188 |
+
}
|
| 189 |
+
yield f"data: {json.dumps(err)}\n\n"
|
| 190 |
+
yield "data: [DONE]\n\n"
|
| 191 |
+
|
| 192 |
# Streaming response
|
| 193 |
|
| 194 |
async def stream_proxy_response(self, request: ChatCompletionRequest) -> AsyncGenerator[str, None]:
|
| 195 |
client = None
|
| 196 |
+
cookie = None
|
| 197 |
try:
|
| 198 |
client = httpx.AsyncClient(
|
| 199 |
timeout=httpx.Timeout(60.0, read=300.0),
|
|
|
|
| 296 |
|
| 297 |
except httpx.RequestError as e:
|
| 298 |
logger.error(f"Request error: {e}")
|
| 299 |
+
if cookie:
|
| 300 |
await cookie_manager.mark_cookie_invalid(cookie)
|
| 301 |
+
async for chunk in self._error_chunks_async(request.model, "Upstream connection error"):
|
| 302 |
+
yield chunk
|
| 303 |
except Exception as e:
|
| 304 |
logger.error(f"Unexpected error: {e}")
|
| 305 |
+
async for chunk in self._error_chunks_async(request.model, "Internal server error"):
|
| 306 |
+
yield chunk
|
| 307 |
finally:
|
| 308 |
if client:
|
| 309 |
await client.aclose()
|
| 310 |
|
| 311 |
async def non_stream_proxy_response(self, request: ChatCompletionRequest):
|
| 312 |
client = None
|
| 313 |
+
cookie = None
|
| 314 |
try:
|
| 315 |
client = httpx.AsyncClient(
|
| 316 |
timeout=httpx.Timeout(60.0, read=300.0),
|
|
|
|
| 378 |
|
| 379 |
except httpx.RequestError as e:
|
| 380 |
logger.error(f"Request error: {e}")
|
| 381 |
+
if cookie:
|
| 382 |
await cookie_manager.mark_cookie_invalid(cookie)
|
| 383 |
raise HTTPException(status_code=502, detail="Upstream connection error")
|
| 384 |
except Exception as e:
|
|
|
|
| 388 |
if client:
|
| 389 |
await client.aclose()
|
| 390 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 391 |
# FastAPI entry point
|
| 392 |
|
| 393 |
async def handle_chat_completion(self, request: ChatCompletionRequest):
|