Ready_Set_Hire / app.py
AnnaMathews's picture
Update app.py
d41636e verified
import os
import gradio as gr
from llama_index.readers.file import PDFReader
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI as LlamaOpenAI
from openai import OpenAI # New SDK
from gtts import gTTS
import random
import tempfile
import speech_recognition as sr
# πŸ” Set API key directly (use HF secret or hardcode for testing)
OPENAI_API_KEY = os.environ.get('HF_OPENAI_API_KEY', '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') # Replace or use HF secret
client = OpenAI(api_key=OPENAI_API_KEY)
# Global state
query_engine = None
resume_summary = ""
questions = []
asked_questions = []
# Step 1: Load and index resume
def load_resume(file):
global query_engine, resume_summary, questions, asked_questions
reader = PDFReader()
documents = reader.load_data(file=file.name)
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
resume_summary = query_engine.query("Summarize this resume in detail.")
prompt = f"Generate 5 personalized interview-style questions based on this resume:\n{resume_summary}"
questions = [str(query_engine.query(prompt + f"\nQuestion {i+1}")) for i in range(5)]
asked_questions = []
return f"βœ… Resume analyzed!\n\nπŸ“„ Summary:\n{resume_summary}"
# Step 2: Ask next question (TTS with gTTS)
def ask_next_question():
global questions, asked_questions
if not questions:
return "❌ Resume not loaded yet.", None
remaining = [q for q in questions if q not in asked_questions]
if not remaining:
return "βœ… All questions have been asked.", None
next_q = random.choice(remaining)
asked_questions.append(next_q)
# Convert text to audio using gTTS
tts = gTTS(next_q)
temp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
tts.save(temp_audio.name)
return next_q, temp_audio.name
# Step 3: Speech to Text
def speech_to_text(audio_path):
recognizer = sr.Recognizer()
with sr.AudioFile(audio_path) as source:
audio_data = recognizer.record(source)
try:
return recognizer.recognize_google(audio_data)
except sr.UnknownValueError:
return "⚠️ Could not understand the voice input."
except sr.RequestError:
return "⚠️ API error with speech recognition."
# Step 4: Evaluate answer using OpenAI SDK v1.0+
def evaluate_answer(audio_path):
if not audio_path:
return "⚠️ Please record an answer.", "❌ No score"
transcript = speech_to_text(audio_path)
if transcript.startswith("⚠️"):
return transcript, "❌"
rating_prompt = f"""
You are an interview evaluator. Rate the following candidate's answer from 1 to 5 based on:
- Relevance
- Clarity
- Completeness
Answer: "{transcript}"
Only return: Score: <number>
"""
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": rating_prompt}],
max_tokens=10,
temperature=0.2,
)
score = response.choices[0].message.content.strip()
return f"πŸ“ Transcript: {transcript}", f"πŸ”Ž {score}"
except Exception as e:
return "❌ Evaluation failed", str(e)
# Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("# 🎀 Voice Resume Interview Bot\nUpload your resume β†’ get questions in voice β†’ answer via mic β†’ get score.")
with gr.Row():
resume_file = gr.File(label="πŸ“„ Upload Resume", file_types=[".pdf"])
resume_summary_box = gr.Textbox(label="Resume Summary", lines=6)
gr.Button("Analyze Resume").click(fn=load_resume, inputs=resume_file, outputs=resume_summary_box)
gr.Markdown("## πŸ”Š Ask a Resume-Based Question")
question_text = gr.Textbox(label="Question", lines=2)
question_audio = gr.Audio(label="Voice", type="filepath", autoplay=True)
gr.Button("Ask Question").click(fn=ask_next_question, outputs=[question_text, question_audio])
gr.Markdown("## πŸŽ™οΈ Speak Your Answer")
user_audio = gr.Audio(label="Record Your Answer", type="filepath")
transcript_output = gr.Textbox(label="Transcript")
score_output = gr.Textbox(label="LLM Score")
gr.Button("Submit Answer").click(fn=evaluate_answer, inputs=user_audio, outputs=[transcript_output, score_output])
demo.launch()