DDI_Endpoint / app.py
rubyseng's picture
create app.py
efef7fb verified
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
import os
import chromadb
from langchain_community.document_loaders.pdf import PyPDFDirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate
# Define the Chatbot class
class DocumentChatbot:
def __init__(self, model_name: str, embedding_model: str, documents_path: str, chroma_path: str):
self.model = ChatOpenAI(model=model_name, temperature=0)
self.text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
self.embeddings = OpenAIEmbeddings(model=embedding_model)
self.db_chroma = self._load_documents(documents_path, chroma_path)
self.prompt_template = """
Answer the question based only on the following context:
{context}
Answer the question based on the above context: {question}.
Provide a detailed answer.
Don’t justify your answers.
Don’t give information not mentioned in the CONTEXT INFORMATION.
Do not say "according to the context" or "mentioned in the context" or similar.
"""
def _load_documents(self, documents_path: str, chroma_path: str):
# Load and process documents
loader = PyPDFDirectoryLoader(documents_path)
pages = loader.load_and_split(self.text_splitter)
db_chroma = Chroma.from_documents(pages, self.embeddings, persist_directory=chroma_path)
return db_chroma
def generate_response(self, message: str):
docs_chroma = self.db_chroma.similarity_search_with_score(message, k=5)
context_text = "\n\n".join([doc.page_content for doc, _score in docs_chroma])
prompt_template = ChatPromptTemplate.from_template(self.prompt_template)
prompt = prompt_template.format(context=context_text, question=message)
response = ""
for chunk in self.model.stream(prompt):
response += chunk.content
return response
# Define the request model
class ChatRequest(BaseModel):
message: str
# Dependency Injection
def get_chatbot():
return DocumentChatbot(
model_name="gpt-4",
embedding_model="text-embedding-3-small",
documents_path="/content/drive/MyDrive/Test Documents", # Update this path as necessary
chroma_path="test-documents-2"
)
# Initialize FastAPI app
app = FastAPI()
# API Endpoint
@app.post("/chat")
async def chat(request: ChatRequest, chatbot: DocumentChatbot = Depends(get_chatbot)):
try:
response = chatbot.generate_response(request.message)
return {"response": response}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# Optional: A health check endpoint
@app.get("/health")
async def health_check():
return {"status": "ok"}