chatbot / main.py
okoliechykwuka
Add root endpoint for Space homepage
d1e2169
from contextlib import asynccontextmanager
from datetime import datetime
from typing import Optional
import uvicorn
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, Field
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from src.chat_service import chat_service
class ChatRequest(BaseModel):
message: str = Field(..., min_length=1, max_length=4096, description="User input message")
thread_id: Optional[str] = Field(default="default", description="Conversation ID for memory tracking")
class ChatResponse(BaseModel):
response: str = Field(..., description="Assistant's response")
thread_id: str = Field(..., description="Conversation ID used for memory tracking")
timestamp: datetime = Field(default_factory=datetime.now)
class HealthResponse(BaseModel):
status: str = Field(..., description="Service status")
timestamp: datetime = Field(default_factory=datetime.now)
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
print("Starting up the application...")
yield
# Shutdown
print("Shutting down the application...")
app = FastAPI(
title="9jaLingo RAG Chat API",
description="RAG API for interacting with the 9jaLingo support chatbot",
version="1.0.0",
lifespan=lifespan
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/", tags=["Health"])
async def root():
return {
"name": "9jaLingo RAG Chat API",
"status": "ok",
"docs": "/docs",
"health": "/health",
}
@app.get("/health",
response_model=HealthResponse,
status_code=status.HTTP_200_OK,
tags=["Health"])
async def health_check():
"""
Endpoint to check if the service is running.
Returns a 200 OK response if the service is healthy.
"""
try:
return HealthResponse(
status="healthy",
timestamp=datetime.now()
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Service health check failed: {str(e)}"
)
@app.post("/chat",
response_model=ChatResponse,
status_code=status.HTTP_200_OK,
tags=["Chat"])
async def chat_endpoint(request: ChatRequest):
try:
thread_id = request.thread_id or "default"
response = chat_service.chat(request.message, thread_id)
return ChatResponse(
response=response,
thread_id=thread_id,
timestamp=datetime.now()
)
except ValueError as ve:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=str(ve)
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error processing chat request: {str(e)}"
)
@app.post("/stream", tags=["Chat"])
async def stream_endpoint(request: ChatRequest):
try:
thread_id = request.thread_id or "default"
def generate():
yield from chat_service.stream(request.message, thread_id)
return StreamingResponse(generate(), media_type="text/plain")
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error streaming chat response: {str(e)}"
)
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=True,
workers=1
)