thelearninghouse-api / services /api /chat_endpoints.py
tlong-ds's picture
redis -> valkey
ccbdc68
from fastapi import APIRouter, Depends, HTTPException, Request, Cookie
from typing import Dict, Optional
from services.api.db.token_utils import decode_token
from services.api.chatbot.core import get_chat_response, get_chat_response_lecture, clear_chat_history, clear_lecture_chat_history
from services.utils.chat_cache import get_chat_history, append_chat_message, clear_user_chat_history
from pydantic import BaseModel
router = APIRouter()
class ChatMessage(BaseModel):
message: str
@router.post("/chat")
async def chat_endpoint(message: ChatMessage, request: Request, auth_token: str = Cookie(None)):
try:
# Verify auth token
if not auth_token:
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('Bearer '):
auth_token = auth_header.split(' ')[1]
if not auth_token:
raise HTTPException(status_code=401, detail="No authentication token provided")
try:
user_data = decode_token(auth_token)
username = user_data.get('username') # Get username from token
if not username:
raise HTTPException(status_code=401, detail="Invalid token: missing username")
except Exception as e:
print(f"Token decode error: {str(e)}")
raise HTTPException(status_code=401, detail="Invalid authentication token")
# Get chatbot response
chat_history = get_chat_history(username)
append_chat_message(username, message.message, is_user=True)
response = get_chat_response(username, message.message)
append_chat_message(username, response, is_user=False)
return {"answer": response, "history": get_chat_history(username)}
except Exception as e:
print(f"Chat error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/chat/lecture/{lecture_id}")
async def lecture_chat_endpoint(
lecture_id: int,
message: ChatMessage,
request: Request,
auth_token: str = Cookie(None)
):
try:
# Verify auth token
if not auth_token:
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('Bearer '):
auth_token = auth_header.split(' ')[1]
if not auth_token:
raise HTTPException(status_code=401, detail="No authentication token provided")
try:
user_data = decode_token(auth_token)
username = user_data.get('username') # Get username from token
if not username:
raise HTTPException(status_code=401, detail="Invalid token: missing username")
except Exception as e:
print(f"Token decode error: {str(e)}")
raise HTTPException(status_code=401, detail="Invalid authentication token")
# Get chatbot response for specific lecture
chat_history = get_chat_history(username)
append_chat_message(username, message.message, is_user=True)
response = get_chat_response_lecture(username, message.message, lecture_id)
append_chat_message(username, response, is_user=False)
return {"answer": response, "history": get_chat_history(username)}
except HTTPException as he:
raise he
except Exception as e:
print(f"Lecture chat error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/chat/history")
async def clear_history_endpoint(request: Request, auth_token: str = Cookie(None), lectureId: Optional[int] = None):
try:
# Verify auth token
if not auth_token:
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('Bearer '):
auth_token = auth_header.split(' ')[1]
if not auth_token:
raise HTTPException(status_code=401, detail="No authentication token provided")
try:
user_data = decode_token(auth_token)
username = user_data.get('username') # Get username from token
if not username:
raise HTTPException(status_code=401, detail="Invalid token: missing username")
except Exception as e:
print(f"Token decode error: {str(e)}")
raise HTTPException(status_code=401, detail="Invalid authentication token")
# Clear Valkey cache
clear_user_chat_history(username)
# Clear memory-based chat histories based on lectureId
if lectureId is not None:
# Only clear the specific lecture chat
clear_lecture_chat_history(username, lectureId)
else:
# Clear both regular and all lecture chat histories for this user
clear_chat_history(username)
clear_lecture_chat_history(username)
# Return empty history for frontend to use
return {"status": "success", "message": "Chat history cleared", "history": []}
except HTTPException as he:
raise he
except Exception as e:
print(f"Clear history error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/chat/history/{lecture_id}")
async def get_history_endpoint(
lecture_id: int,
request: Request,
auth_token: str = Cookie(None)
):
try:
# Verify auth token
if not auth_token:
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('Bearer '):
auth_token = auth_header.split(' ')[1]
if not auth_token:
raise HTTPException(status_code=401, detail="No authentication token provided")
try:
user_data = decode_token(auth_token)
username = user_data.get('username') # Get username from token
if not username:
raise HTTPException(status_code=401, detail="Invalid token: missing username")
except Exception as e:
print(f"Token decode error: {str(e)}")
raise HTTPException(status_code=401, detail="Invalid authentication token")
# Get chat history from Valkey
chat_history = get_chat_history(username)
# Return the chat history - make sure formatting is consistent
return {"history": chat_history, "message": "History retrieved successfully"}
except HTTPException as he:
raise he
except Exception as e:
print(f"Get history error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/chat/history")
async def get_general_history_endpoint(
request: Request,
auth_token: str = Cookie(None)
):
try:
# Verify auth token
if not auth_token:
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('Bearer '):
auth_token = auth_header.split(' ')[1]
if not auth_token:
raise HTTPException(status_code=401, detail="No authentication token provided")
try:
user_data = decode_token(auth_token)
username = user_data.get('username') # Get username from token
if not username:
raise HTTPException(status_code=401, detail="Invalid token: missing username")
except Exception as e:
print(f"Token decode error: {str(e)}")
raise HTTPException(status_code=401, detail="Invalid authentication token")
# Get chat history from Valkey
chat_history = get_chat_history(username)
# Return the chat history with a debugging message
print(f"Returning chat history for {username}: {len(chat_history)} messages")
return {"history": chat_history, "message": "History retrieved successfully"}
except HTTPException as he:
raise he
except Exception as e:
print(f"Get history error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))