Alexvatti's picture
Create app.py
1bb7c15 verified
from fastapi import FastAPI, UploadFile, File
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import pandas as pd
from sentence_transformers import SentenceTransformer
import numpy as np
import faiss
app = FastAPI(title="Closed-Domain Q&A Chatbot")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# Data store
questions = []
answers = []
index = None
model = None
class Question(BaseModel):
query: str
@app.post("/load")
async def load_qa(file: UploadFile = File(...)):
global questions, answers, index, model
if file.filename.endswith(".csv"):
df = pd.read_csv(file.file)
elif file.filename.endswith((".xls", ".xlsx")):
df = pd.read_excel(file.file)
else:
return {"error": "Unsupported file format."}
if "Question" not in df.columns or "Answer" not in df.columns:
return {"error": "Columns 'Question' and 'Answer' required."}
questions = df["Question"].tolist()
answers = df["Answer"].tolist()
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
question_embeddings = model.encode(questions)
index = faiss.IndexFlatL2(question_embeddings.shape[1])
index.add(np.array(question_embeddings).astype('float32'))
return {"status": "Knowledge base loaded", "total_questions": len(questions)}
@app.post("/clear")
async def clear_data():
global questions, answers, index, model
questions, answers, index, model = [], [], None, None
return {"status": "Knowledge base cleared"}
@app.post("/ask")
async def ask_question(question: Question):
if not index:
return {"answer": "Knowledge base not loaded"}
query_embedding = model.encode([question.query]).astype('float32')
D, I = index.search(query_embedding, k=1)
if D[0][0] < 50: # Distance threshold
matched_answer = answers[I[0][0]]
return {"answer": matched_answer}
else:
return {"answer": "I don’t have an answer for that."}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)