Spaces:
Runtime error
Runtime error
File size: 6,776 Bytes
5348e91 8f736d9 5348e91 2c970f4 5348e91 2c970f4 5348e91 2c970f4 5348e91 2c970f4 5348e91 2c970f4 5348e91 2c970f4 5348e91 8f736d9 5348e91 abcd0f0 5348e91 abcd0f0 7f1907b 5348e91 8f736d9 5348e91 8f736d9 5348e91 2c970f4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# app.py
import gradio as gr
import os
import time
import datetime
import random
import config
from modules.tts_handler import text_to_speech_file
from modules.stt_handler import transcribe_audio
from modules.doc_processor import extract_text_from_document
from modules.llm_handler import generate_question, evaluate_answer
from modules.report_generator import generate_pdf_report
def start_interview(interview_type, doc_file, name, num_questions):
if not interview_type or not doc_file:
return {
chatbot: gr.update(value=[[None, "Please select an interview type and upload a document to begin."]]),
audio_in: gr.update(interactive=False)
}
doc_text = extract_text_from_document(doc_file.name)
if "Error" in doc_text or "Unsupported" in doc_text:
return {
chatbot: gr.update(value=[[None, f"Error: {doc_text}"]]),
audio_in: gr.update(interactive=False)
}
initial_state = {
"interview_type": interview_type,
"doc_text": doc_text,
"name": name if name else "User",
"question_count": int(num_questions),
"current_question_num": 1,
"interview_log": [],
"start_time": time.time()
}
first_question = generate_question(interview_type, doc_text)
initial_state["current_question_text"] = first_question
greeting = f"Hello {initial_state['name']}. We'll go through {int(num_questions)} questions today. Here is your first question:"
tts_prompt = f"{greeting} {first_question}"
# Try to generate TTS audio, but don't fail if it's not available
try:
ai_voice_path = text_to_speech_file(tts_prompt)
except Exception as e:
print(f"TTS generation failed: {e}")
ai_voice_path = None
return {
state: initial_state,
chatbot: gr.update(value=[[None, f"{greeting}\n\n{first_question}"]]),
audio_out: gr.update(value=ai_voice_path, autoplay=True if ai_voice_path else False),
audio_in: gr.update(interactive=True),
start_btn: gr.update(interactive=False)
}
def handle_interview_turn(user_audio, chatbot_history, current_state):
user_answer_text = transcribe_audio(user_audio)
chatbot_history.append([user_answer_text, None])
yield {chatbot: chatbot_history, audio_in: gr.update(interactive=False)}
evaluation_text = evaluate_answer(current_state["current_question_text"], user_answer_text)
current_state["interview_log"].append({
"question": current_state["current_question_text"],
"answer": user_answer_text,
"evaluation": evaluation_text
})
if current_state["current_question_num"] >= current_state["question_count"]:
end_message = "This concludes the interview. Generating your final report now."
chatbot_history.append([None, end_message])
pdf_path = generate_pdf_file(current_state)
# Try to generate TTS audio, but don't fail if it's not available
try:
ai_voice_path = text_to_speech_file(end_message)
except Exception as e:
print(f"TTS generation failed: {e}")
ai_voice_path = None
yield {
chatbot: chatbot_history,
audio_out: gr.update(value=ai_voice_path, autoplay=True if ai_voice_path else False),
download_pdf_btn: gr.update(value=pdf_path, visible=True)
}
else:
current_state["current_question_num"] += 1
next_question = generate_question(current_state["interview_type"], current_state["doc_text"])
current_state["current_question_text"] = next_question
q_num = current_state["current_question_num"]
transition_message = f"Thank you. Here is question {q_num}:\n\n{next_question}"
chatbot_history.append([None, transition_message])
# Try to generate TTS audio, but don't fail if it's not available
try:
ai_voice_path = text_to_speech_file(transition_message)
except Exception as e:
print(f"TTS generation failed: {e}")
ai_voice_path = None
yield {
state: current_state,
chatbot: chatbot_history,
audio_out: gr.update(value=ai_voice_path, autoplay=True if ai_voice_path else False),
audio_in: gr.update(interactive=True)
}
def generate_pdf_file(state):
total_duration_minutes = (time.time() - state.get("start_time", time.time())) / 60
final_data = {
"name": state.get("name", "N/A"),
"type": state.get("interview_type", "N/A"),
"duration": total_duration_minutes,
"q_and_a": state.get("interview_log", [])
}
file_name = f"Report_{state.get('name', 'User')}_{datetime.datetime.now().strftime('%Y-%m-%d')}.pdf"
file_path = os.path.join(config.REPORT_FOLDER, file_name)
generate_pdf_report(final_data, file_path)
return file_path
with gr.Blocks(theme=gr.themes.Default()) as app:
state = gr.State({})
gr.Markdown("# PM Interview Coach")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Setup")
user_name = gr.Textbox(label="Your Name")
interview_type_dd = gr.Dropdown(config.INTERVIEW_TYPES, label="Interview Type")
num_questions_slider = gr.Slider(minimum=1, maximum=10, value=5, step=1, label="Number of Questions")
# --- THIS IS THE UPDATED COMPONENT ---
doc_uploader = gr.File(
label="Upload Resume/CV (.pdf, .docx)",
file_types=['.pdf', '.docx']
)
start_btn = gr.Button("Start Interview", variant="primary")
with gr.Column(scale=2):
chatbot = gr.Chatbot(label="Conversation", height=500)
audio_in = gr.Audio(sources=["microphone"], type="filepath", label="Record Your Answer", interactive=False)
download_pdf_btn = gr.File(label="Download Report", visible=False)
audio_out = gr.Audio(visible=False, autoplay=True)
start_btn.click(
fn=start_interview,
inputs=[interview_type_dd, doc_uploader, user_name, num_questions_slider],
outputs=[state, chatbot, audio_out, audio_in, start_btn]
)
audio_in.stop_recording(
fn=handle_interview_turn,
inputs=[audio_in, chatbot, state],
outputs=[state, chatbot, audio_out, audio_in, download_pdf_btn]
)
if __name__ == "__main__":
os.makedirs(config.UPLOAD_FOLDER, exist_ok=True)
os.makedirs(config.REPORT_FOLDER, exist_ok=True)
# Configure for Hugging Face Spaces deployment
app.launch(
server_name="0.0.0.0",
server_port=7860,
share=False
) |