102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
# api/v1/sessions.py
|
|
|
|
from typing import List, Optional
|
|
from fastapi import Body, Query, Path, WebSocket, WebSocketDisconnect
|
|
from services import redis_service
|
|
from fastapi import APIRouter
|
|
from models.session import SessionMeta
|
|
import json
|
|
import asyncio
|
|
|
|
router = APIRouter()
|
|
|
|
# -------------------------
|
|
# WebSocket per aggiornamenti sessioni
|
|
# -------------------------
|
|
@router.websocket("/ws/sessions")
|
|
async def sessions_ws(websocket: WebSocket, user_id: str = Query(...)):
|
|
await websocket.accept()
|
|
try:
|
|
sessions = redis_service.get_sessions(user_id)
|
|
await websocket.send_json({"type": "full_list", "sessions": sessions})
|
|
|
|
pubsub = redis_service.r.pubsub()
|
|
channel = f"sessions:{user_id}"
|
|
await pubsub.subscribe(channel)
|
|
|
|
async for message in pubsub.listen():
|
|
if message["type"] != "message":
|
|
continue
|
|
try:
|
|
data = json.loads(message["data"])
|
|
await websocket.send_json(data)
|
|
except Exception as e:
|
|
print(f"[WS] Errore parsing messaggio: {e}")
|
|
|
|
except WebSocketDisconnect:
|
|
print(f"[WS] Disconnesso: {user_id}")
|
|
finally:
|
|
await pubsub.unsubscribe(channel)
|
|
await pubsub.close()
|
|
|
|
# -------------------------
|
|
# Endpoint REST
|
|
# -------------------------
|
|
|
|
@router.get("/sessions", response_model=List[dict])
|
|
async def list_sessions_endpoint(user_id: str = Query(...)):
|
|
return redis_service.get_sessions(user_id)
|
|
|
|
@router.get("/sessions/{session_id}", response_model=dict)
|
|
async def get_session_meta_endpoint(
|
|
user_id: str = Query(..., description="User ID"),
|
|
session_id: str = Path(..., description="Session ID")
|
|
):
|
|
return redis_service.get_session_meta(user_id, session_id) or {}
|
|
|
|
@router.post("/sessions", response_model=dict)
|
|
async def create_session_endpoint(
|
|
user_id: str = Query(..., description="User ID"),
|
|
first_message: str = Body("", embed=True),
|
|
model_name: Optional[str] = Body(None, embed=True) # <-- Accept model_name
|
|
):
|
|
meta = redis_service.create_session(user_id, first_message, model_name=model_name)
|
|
redis_service.r.publish(
|
|
f"sessions:{user_id}",
|
|
json.dumps({"type": "created", "session": meta})
|
|
)
|
|
return meta
|
|
|
|
@router.patch("/sessions/{session_id}", response_model=dict)
|
|
async def update_session_endpoint(
|
|
user_id: str = Query(..., description="User ID"),
|
|
session_id: str = Path(..., description="Session ID"),
|
|
session_name: Optional[str] = Body(None, embed=True),
|
|
model_name: Optional[str] = Body(None, embed=True) # <-- Allow model update
|
|
):
|
|
updated = redis_service.update_session_meta(
|
|
user_id, session_id,
|
|
session_name=session_name,
|
|
model_name=model_name
|
|
) or {}
|
|
|
|
if updated:
|
|
redis_service.r.publish(
|
|
f"sessions:{user_id}",
|
|
json.dumps({"type": "updated", "session": updated})
|
|
)
|
|
return updated
|
|
|
|
@router.delete("/sessions/{session_id}", response_model=dict)
|
|
async def delete_session_endpoint(
|
|
user_id: str = Query(..., description="User ID"),
|
|
session_id: str = Path(..., description="Session ID")
|
|
):
|
|
redis_service.delete_session(user_id, session_id)
|
|
redis_service.r.publish(
|
|
f"sessions:{user_id}",
|
|
json.dumps({"type": "deleted", "session_id": session_id})
|
|
)
|
|
return {"status": "deleted"}
|
|
|