Spaces:
Sleeping
Sleeping
Commit ·
311fd07
1
Parent(s): 8cc8f94
commit 000000239
Browse files
app.py
CHANGED
|
@@ -2,8 +2,7 @@ import os
|
|
| 2 |
import time
|
| 3 |
import torch
|
| 4 |
import re
|
| 5 |
-
from fastapi import FastAPI, Request
|
| 6 |
-
from fastapi.responses import StreamingResponse
|
| 7 |
from fastapi.staticfiles import StaticFiles
|
| 8 |
from fastapi.templating import Jinja2Templates
|
| 9 |
from pydantic import BaseModel
|
|
@@ -24,15 +23,15 @@ app = FastAPI(
|
|
| 24 |
title="ChatMate Real-Time API",
|
| 25 |
description="LangChain + DuckDuckGo + Phi-4",
|
| 26 |
version="1.0",
|
| 27 |
-
docs_url="/apidocs",
|
| 28 |
-
redoc_url="/redoc"
|
| 29 |
)
|
| 30 |
|
| 31 |
# ✅ Static + templates
|
| 32 |
app.mount("/static", StaticFiles(directory="static"), name="static")
|
| 33 |
templates = Jinja2Templates(directory="templates")
|
| 34 |
|
| 35 |
-
# Enable CORS
|
| 36 |
app.add_middleware(
|
| 37 |
CORSMiddleware,
|
| 38 |
allow_origins=["*"],
|
|
@@ -94,24 +93,38 @@ class ChatRequest(BaseModel):
|
|
| 94 |
message: str
|
| 95 |
history: list = []
|
| 96 |
|
| 97 |
-
# ---------------- FastAPI route ----------------
|
| 98 |
# ---------------- Routes ----------------
|
| 99 |
@app.get("/", summary="Serve homepage")
|
| 100 |
async def home(request: Request):
|
| 101 |
return templates.TemplateResponse("index.html", {"request": request})
|
| 102 |
|
| 103 |
-
@app.
|
| 104 |
-
async def
|
| 105 |
"""
|
| 106 |
-
|
| 107 |
"""
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
# ---------------- Startup warm-up ----------------
|
| 117 |
@app.on_event("startup")
|
|
@@ -120,10 +133,6 @@ async def warmup_model():
|
|
| 120 |
_ = generate_full_reply("Hello", [])
|
| 121 |
|
| 122 |
# ---------------- Run with Uvicorn ----------------
|
| 123 |
-
# In Hugging Face Spaces, just run: uvicorn app:app --host 0.0.0.0 --port 7860
|
| 124 |
if __name__ == "__main__":
|
| 125 |
-
# Hugging Face Spaces usually expects port 7860
|
| 126 |
port = int(os.environ.get("PORT", 7860))
|
| 127 |
-
|
| 128 |
-
# Run using uvicorn for FastAPI/Flask with ASGI wrapper
|
| 129 |
-
uvicorn.run("app:app", host="0.0.0.0", port=port, reload=False)
|
|
|
|
| 2 |
import time
|
| 3 |
import torch
|
| 4 |
import re
|
| 5 |
+
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
|
|
|
|
| 6 |
from fastapi.staticfiles import StaticFiles
|
| 7 |
from fastapi.templating import Jinja2Templates
|
| 8 |
from pydantic import BaseModel
|
|
|
|
| 23 |
title="ChatMate Real-Time API",
|
| 24 |
description="LangChain + DuckDuckGo + Phi-4",
|
| 25 |
version="1.0",
|
| 26 |
+
docs_url="/apidocs",
|
| 27 |
+
redoc_url="/redoc"
|
| 28 |
)
|
| 29 |
|
| 30 |
# ✅ Static + templates
|
| 31 |
app.mount("/static", StaticFiles(directory="static"), name="static")
|
| 32 |
templates = Jinja2Templates(directory="templates")
|
| 33 |
|
| 34 |
+
# Enable CORS
|
| 35 |
app.add_middleware(
|
| 36 |
CORSMiddleware,
|
| 37 |
allow_origins=["*"],
|
|
|
|
| 93 |
message: str
|
| 94 |
history: list = []
|
| 95 |
|
|
|
|
| 96 |
# ---------------- Routes ----------------
|
| 97 |
@app.get("/", summary="Serve homepage")
|
| 98 |
async def home(request: Request):
|
| 99 |
return templates.TemplateResponse("index.html", {"request": request})
|
| 100 |
|
| 101 |
+
@app.websocket("/chat-stream")
|
| 102 |
+
async def chat_stream_ws(websocket: WebSocket):
|
| 103 |
"""
|
| 104 |
+
WebSocket endpoint to stream tokens to the client.
|
| 105 |
"""
|
| 106 |
+
await websocket.accept()
|
| 107 |
+
try:
|
| 108 |
+
while True:
|
| 109 |
+
data = await websocket.receive_text()
|
| 110 |
+
try:
|
| 111 |
+
req = ChatRequest.parse_raw(data)
|
| 112 |
+
except Exception as e:
|
| 113 |
+
await websocket.send_text(f"[Error] Invalid request: {str(e)}")
|
| 114 |
+
continue
|
| 115 |
|
| 116 |
+
reply = generate_full_reply(req.message, req.history)
|
| 117 |
+
|
| 118 |
+
# Stream token by token
|
| 119 |
+
for token in reply:
|
| 120 |
+
await websocket.send_text(token)
|
| 121 |
+
await asyncio.sleep(0.05)
|
| 122 |
+
|
| 123 |
+
# Optional: send special marker to indicate completion
|
| 124 |
+
await websocket.send_text("[END]")
|
| 125 |
+
|
| 126 |
+
except WebSocketDisconnect:
|
| 127 |
+
print("Client disconnected from WebSocket.")
|
| 128 |
|
| 129 |
# ---------------- Startup warm-up ----------------
|
| 130 |
@app.on_event("startup")
|
|
|
|
| 133 |
_ = generate_full_reply("Hello", [])
|
| 134 |
|
| 135 |
# ---------------- Run with Uvicorn ----------------
|
|
|
|
| 136 |
if __name__ == "__main__":
|
|
|
|
| 137 |
port = int(os.environ.get("PORT", 7860))
|
| 138 |
+
uvicorn.run("app:app", host="0.0.0.0", port=port, reload=False)
|
|
|
|
|
|