resume / app.py
AnwinMJ's picture
Update app.py
816aa51 verified
import gradio as gr
from PyPDF2 import PdfReader
from sentence_transformers import SentenceTransformer
import faiss
import os
from openai import OpenAI
# πŸ” Set your OpenAI API key securely
os.environ['OPENAI_API_KEY'] = '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' # Replace with your actual key
client = OpenAI(api_key=os.environ['OPENAI_API_KEY'])
# βœ… Load the sentence-transformer embedding model
embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
# βœ… Extract text from PDF using PyPDF2
def extract_text_from_pdf(pdf_file):
try:
reader = PdfReader(pdf_file)
text = ""
for page in reader.pages:
page_text = page.extract_text() or ""
text += page_text
return text
except Exception as e:
return ""
# βœ… Create a FAISS index for semantic similarity search
def create_vector_index(sentences):
embeddings = embedding_model.encode(sentences)
index = faiss.IndexFlatL2(embeddings.shape[1])
index.add(embeddings)
return index, embeddings
# βœ… Main function to answer question using RAG + OpenAI
def answer_question(pdf, question):
try:
if pdf is None:
return "⚠ Please upload a PDF first."
# Extract and clean text
text = extract_text_from_pdf(pdf)
if not text.strip():
return "⚠ No extractable text found in the PDF."
# Simple sentence-based chunking
chunks = [chunk.strip() for chunk in text.split(". ") if len(chunk.strip()) > 30]
if len(chunks) < 3:
return "⚠ Not enough meaningful content to generate an answer."
# Create vector index
index, _ = create_vector_index(chunks)
# Embed question and search top 3 similar chunks
q_embed = embedding_model.encode([question])
_, I = index.search(q_embed, k=3)
retrieved = [chunks[i] for i in I[0]]
context = "\n".join(retrieved)
# Create prompt and query OpenAI GPT
prompt = f"Context:\n{context}\n\nQuestion: {question}\nAnswer:"
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content.strip()
except Exception as e:
return f"❌ Error: {str(e)}"
# βœ… Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("## 🧠 Resume Q&A Chatbot\nAsk questions about your uploaded resume.")
with gr.Row():
pdf_input = gr.File(label="Upload your Resume PDF", file_types=[".pdf"])
question = gr.Textbox(label="Enter your question")
with gr.Row():
submit_btn = gr.Button("Submit")
clear_btn = gr.Button("Clear")
output = gr.Textbox(label="Answer")
submit_btn.click(fn=answer_question, inputs=[pdf_input, question], outputs=output)
clear_btn.click(lambda: "", inputs=[], outputs=output)
# βœ… Launch the app
demo.launch()