Spaces:
Running
Running
Update app.py
#5
by incognitolm - opened
app.py
CHANGED
|
@@ -1061,16 +1061,22 @@ async def tiers():
|
|
| 1061 |
async def websocket_chat(ws: WebSocket):
|
| 1062 |
ip = ws.client.host
|
| 1063 |
|
|
|
|
| 1064 |
await ws.accept()
|
| 1065 |
|
| 1066 |
-
#
|
| 1067 |
if not check_ws_auth_rate_limit(ip):
|
| 1068 |
await ws.close(code=4408)
|
| 1069 |
return
|
| 1070 |
|
| 1071 |
try:
|
|
|
|
| 1072 |
auth_msg = await ws.receive_text()
|
| 1073 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1074 |
|
| 1075 |
provided_key = auth_data.get("key")
|
| 1076 |
|
|
@@ -1078,45 +1084,97 @@ async def websocket_chat(ws: WebSocket):
|
|
| 1078 |
await ws.close(code=4403)
|
| 1079 |
return
|
| 1080 |
|
| 1081 |
-
#
|
| 1082 |
-
await ws.send_json({
|
| 1083 |
-
|
| 1084 |
-
|
| 1085 |
-
|
| 1086 |
-
|
| 1087 |
-
|
| 1088 |
-
|
| 1089 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1090 |
|
| 1091 |
-
|
| 1092 |
-
|
| 1093 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1094 |
|
| 1095 |
-
|
| 1096 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1097 |
|
| 1098 |
-
|
| 1099 |
-
|
| 1100 |
-
|
| 1101 |
-
|
| 1102 |
-
json=body,
|
| 1103 |
-
headers=headers,
|
| 1104 |
-
) as r:
|
| 1105 |
|
| 1106 |
-
|
| 1107 |
-
|
| 1108 |
-
|
|
|
|
| 1109 |
|
| 1110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1111 |
|
| 1112 |
except WebSocketDisconnect:
|
| 1113 |
return
|
|
|
|
| 1114 |
except Exception as e:
|
| 1115 |
try:
|
| 1116 |
-
await ws.send_json({
|
| 1117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1118 |
pass
|
| 1119 |
-
await ws.close()
|
| 1120 |
|
| 1121 |
@app.get("/portal")
|
| 1122 |
@app.post("/portal")
|
|
|
|
| 1061 |
async def websocket_chat(ws: WebSocket):
|
| 1062 |
ip = ws.client.host
|
| 1063 |
|
| 1064 |
+
# Accept connection
|
| 1065 |
await ws.accept()
|
| 1066 |
|
| 1067 |
+
# Basic connection rate limiting
|
| 1068 |
if not check_ws_auth_rate_limit(ip):
|
| 1069 |
await ws.close(code=4408)
|
| 1070 |
return
|
| 1071 |
|
| 1072 |
try:
|
| 1073 |
+
# Expect an auth message first
|
| 1074 |
auth_msg = await ws.receive_text()
|
| 1075 |
+
try:
|
| 1076 |
+
auth_data = json.loads(auth_msg)
|
| 1077 |
+
except Exception:
|
| 1078 |
+
await ws.close(code=4400)
|
| 1079 |
+
return
|
| 1080 |
|
| 1081 |
provided_key = auth_data.get("key")
|
| 1082 |
|
|
|
|
| 1084 |
await ws.close(code=4403)
|
| 1085 |
return
|
| 1086 |
|
| 1087 |
+
# Auth success
|
| 1088 |
+
await ws.send_json({
|
| 1089 |
+
"type": "auth",
|
| 1090 |
+
"status": "ok"
|
| 1091 |
+
})
|
| 1092 |
+
|
| 1093 |
+
# Internal endpoint (avoids Hugging Face proxy redirect)
|
| 1094 |
+
internal_url = "http://127.0.0.1:7860/gen/chat/completions"
|
| 1095 |
+
|
| 1096 |
+
# Persistent HTTP client for streaming
|
| 1097 |
+
async with httpx.AsyncClient(
|
| 1098 |
+
timeout=None,
|
| 1099 |
+
follow_redirects=False
|
| 1100 |
+
) as client:
|
| 1101 |
+
|
| 1102 |
+
while True:
|
| 1103 |
+
try:
|
| 1104 |
+
msg = await ws.receive_text()
|
| 1105 |
+
except WebSocketDisconnect:
|
| 1106 |
+
break
|
| 1107 |
+
|
| 1108 |
+
try:
|
| 1109 |
+
data = json.loads(msg)
|
| 1110 |
+
except Exception:
|
| 1111 |
+
await ws.send_json({"error": "Invalid JSON"})
|
| 1112 |
+
continue
|
| 1113 |
+
|
| 1114 |
+
body = data.get("body")
|
| 1115 |
+
headers = data.get("headers") or {}
|
| 1116 |
+
|
| 1117 |
+
if not body:
|
| 1118 |
+
await ws.send_json({"error": "Missing body"})
|
| 1119 |
+
continue
|
| 1120 |
+
|
| 1121 |
+
try:
|
| 1122 |
+
async with client.stream(
|
| 1123 |
+
"POST",
|
| 1124 |
+
internal_url,
|
| 1125 |
+
json=body,
|
| 1126 |
+
headers=headers
|
| 1127 |
+
) as response:
|
| 1128 |
|
| 1129 |
+
# Handle upstream errors
|
| 1130 |
+
if response.status_code >= 400:
|
| 1131 |
+
error_text = ""
|
| 1132 |
+
try:
|
| 1133 |
+
error_text = (await response.aread()).decode(
|
| 1134 |
+
"utf-8", errors="replace"
|
| 1135 |
+
)[:500]
|
| 1136 |
+
except Exception:
|
| 1137 |
+
pass
|
| 1138 |
|
| 1139 |
+
await ws.send_json({
|
| 1140 |
+
"error": "Upstream request failed",
|
| 1141 |
+
"status": response.status_code,
|
| 1142 |
+
"detail": error_text
|
| 1143 |
+
})
|
| 1144 |
+
continue
|
| 1145 |
|
| 1146 |
+
# Stream tokens/lines to the websocket
|
| 1147 |
+
async for line in response.aiter_lines():
|
| 1148 |
+
if not line:
|
| 1149 |
+
continue
|
|
|
|
|
|
|
|
|
|
| 1150 |
|
| 1151 |
+
try:
|
| 1152 |
+
await ws.send_text(line)
|
| 1153 |
+
except RuntimeError:
|
| 1154 |
+
break
|
| 1155 |
|
| 1156 |
+
except Exception as stream_error:
|
| 1157 |
+
await ws.send_json({
|
| 1158 |
+
"error": "Streaming error",
|
| 1159 |
+
"detail": str(stream_error)
|
| 1160 |
+
})
|
| 1161 |
|
| 1162 |
except WebSocketDisconnect:
|
| 1163 |
return
|
| 1164 |
+
|
| 1165 |
except Exception as e:
|
| 1166 |
try:
|
| 1167 |
+
await ws.send_json({
|
| 1168 |
+
"error": "Server error",
|
| 1169 |
+
"detail": str(e)
|
| 1170 |
+
})
|
| 1171 |
+
except Exception:
|
| 1172 |
+
pass
|
| 1173 |
+
|
| 1174 |
+
try:
|
| 1175 |
+
await ws.close()
|
| 1176 |
+
except Exception:
|
| 1177 |
pass
|
|
|
|
| 1178 |
|
| 1179 |
@app.get("/portal")
|
| 1180 |
@app.post("/portal")
|