tejaskkkk's picture
Upload 7 files
d080d3f verified
raw
history blame
4.33 kB
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import logging
import time
import utils
import config
from langsmith import Client
from langsmith.run_helpers import traceable
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Initialize logging
logger = logging.getLogger("swayam-chatbot")
# Initialize LangSmith client if tracing is enabled
langsmith_tracing = os.environ.get("LANGSMITH_TRACING", "false").lower() == "true"
langsmith_client = None
if langsmith_tracing:
try:
langsmith_client = Client()
logger.info("LangSmith client initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize LangSmith client: {e}")
langsmith_tracing = False
# Initialize FastAPI app
app = FastAPI(title="Swayam's Personal Chatbot API")
# Add CORS middleware to allow requests from the portfolio website
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # For production, replace with actual domain
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class ChatRequest(BaseModel):
query: str
class ChatResponse(BaseModel):
response: str
type: str # "personal" or "general"
processing_time: float
format: str = "markdown" # Add format field to indicate response format
@app.on_event("startup")
async def startup_event():
"""Load resources on startup"""
success = utils.load_resources()
if not success:
logger.error("Failed to load embedding resources. RAG functionality will not work.")
@traceable(run_type="chain", name="Swayam Chatbot Request")
def process_chat_request(query: str):
"""Process a chat request with LangSmith tracing"""
# Determine if query is personal
is_personal = utils.is_personal_query(query)
query_type = "personal" if is_personal else "general"
# Get relevant context if personal query
context = ""
if is_personal:
context = utils.get_relevant_context(query)
# Generate response
result = utils.generate_response(query)
return {
"response": result["response"],
"type": query_type,
"context_used": context[:200] + "..." if context else "None"
}
@app.post("/chat", response_model=ChatResponse)
async def chat_endpoint(request: ChatRequest):
"""Endpoint to handle chat requests"""
start_time = time.time()
# Log the incoming request
logger.info(f"Received query: {request.query}")
if not request.query or request.query.strip() == "":
raise HTTPException(status_code=400, detail="Query cannot be empty")
# Generate response with or without LangSmith tracing
if langsmith_tracing:
try:
trace_result = process_chat_request(request.query)
result = {"response": trace_result["response"], "type": trace_result["type"]}
except Exception as e:
logger.error(f"Error in LangSmith traced processing: {e}")
# Fall back to non-traced processing
result = utils.generate_response(request.query)
else:
# Standard processing without tracing
result = utils.generate_response(request.query)
# Calculate processing time
processing_time = time.time() - start_time
# Log the response
logger.info(f"Response type: {result['type']}, Processing time: {processing_time:.2f}s")
return ChatResponse(
response=result["response"],
type=result["type"],
processing_time=processing_time,
format="markdown" # Always return markdown format
)
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {"status": "ok", "embeddings_loaded": utils.embeddings is not None}
# Add this below your existing health check endpoint
@app.head("/")
async def head_request():
"""HEAD request endpoint to check if server is running"""
# This returns just the headers, no body content
return {}
if __name__ == "__main__":
import uvicorn
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)