add face
This commit is contained in:
BIN
Binary file not shown.
Executable
+64
@@ -0,0 +1,64 @@
|
||||
import asyncio
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import StreamingResponse, JSONResponse
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
clients: set[asyncio.Queue[str]] = set()
|
||||
current_emotion = "neutral"
|
||||
|
||||
def sse(event: str, data: str) -> str:
|
||||
# SSE format: event + data + blank line
|
||||
return f"event: {event}\ndata: {data}\n\n"
|
||||
|
||||
@app.get("/events")
|
||||
async def events(request: Request):
|
||||
"""
|
||||
Browser connects here via EventSource. We stream emotion updates.
|
||||
"""
|
||||
q: asyncio.Queue[str] = asyncio.Queue()
|
||||
clients.add(q)
|
||||
|
||||
async def gen():
|
||||
try:
|
||||
# send current state immediately
|
||||
yield sse("emotion", current_emotion)
|
||||
|
||||
while True:
|
||||
# abort if client disconnected
|
||||
if await request.is_disconnected():
|
||||
break
|
||||
|
||||
msg = await q.get()
|
||||
yield sse("emotion", msg)
|
||||
finally:
|
||||
clients.discard(q)
|
||||
|
||||
headers = {
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no", # helpful behind nginx
|
||||
}
|
||||
return StreamingResponse(gen(), media_type="text/event-stream", headers=headers)
|
||||
|
||||
@app.post("/api/emotion/{name}")
|
||||
async def set_emotion(name: str):
|
||||
global current_emotion
|
||||
current_emotion = name
|
||||
|
||||
# broadcast to all connected clients
|
||||
dead = []
|
||||
for q in clients:
|
||||
try:
|
||||
q.put_nowait(name)
|
||||
except Exception:
|
||||
dead.append(q)
|
||||
for q in dead:
|
||||
clients.discard(q)
|
||||
|
||||
return JSONResponse({"ok": True, "emotion": current_emotion})
|
||||
|
||||
@app.get("/api/emotion")
|
||||
async def get_emotion():
|
||||
return {"emotion": current_emotion}
|
||||
|
||||
Reference in New Issue
Block a user