Update app.py
Browse files
app.py
CHANGED
|
@@ -245,17 +245,32 @@ def process_resume(file_obj):
|
|
| 245 |
except Exception as e:
|
| 246 |
return f"Error processing file: {str(e)}", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), None
|
| 247 |
|
|
|
|
|
|
|
| 248 |
def start_interview(roles, processed_resume_data):
|
| 249 |
"""Starts the interview process."""
|
| 250 |
if not roles or not processed_resume_data:
|
| 251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
|
| 253 |
try:
|
| 254 |
questions = generate_questions(roles, processed_resume_data)
|
| 255 |
initial_question = questions[0] if questions else "Could you please introduce yourself?"
|
| 256 |
|
| 257 |
# Initialize state for the interview
|
| 258 |
-
|
| 259 |
"questions": questions,
|
| 260 |
"current_q_index": 0,
|
| 261 |
"answers": [],
|
|
@@ -265,27 +280,36 @@ def start_interview(roles, processed_resume_data):
|
|
| 265 |
"resume_data": processed_resume_data
|
| 266 |
}
|
| 267 |
|
|
|
|
| 268 |
return (
|
| 269 |
"Interview started. Please answer the first question.",
|
| 270 |
initial_question,
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
gr.update(visible=
|
| 276 |
-
gr.update(visible=
|
| 277 |
-
gr.update(visible=True), #
|
| 278 |
-
gr.update(visible=
|
| 279 |
-
|
| 280 |
-
gr.update(visible=False), # Metrics display
|
| 281 |
-
gr.update(visible=False), # Evaluation button (hidden initially)
|
| 282 |
-
gr.update(visible=True), # Question display
|
| 283 |
-
gr.update(visible=True), # Answer instructions
|
| 284 |
-
interview_state
|
| 285 |
)
|
| 286 |
except Exception as e:
|
| 287 |
-
|
| 288 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
def submit_answer(audio, interview_state):
|
| 290 |
"""Handles submitting an answer via audio."""
|
| 291 |
if not audio or not interview_state:
|
|
@@ -451,34 +475,65 @@ with gr.Blocks(title="PrepGenie - Mock Interview") as demo:
|
|
| 451 |
|
| 452 |
# --- Event Listeners ---
|
| 453 |
|
| 454 |
-
# Process Resume
|
| 455 |
process_btn.click(
|
| 456 |
fn=process_resume,
|
| 457 |
inputs=[file_upload],
|
| 458 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
)
|
| 460 |
|
| 461 |
# Start Interview
|
| 462 |
start_interview_btn.click(
|
| 463 |
fn=start_interview,
|
| 464 |
inputs=[role_selection, processed_resume_data],
|
| 465 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
)
|
| 467 |
|
|
|
|
|
|
|
| 468 |
# Submit Answer
|
| 469 |
submit_answer_btn.click(
|
| 470 |
fn=submit_answer,
|
| 471 |
inputs=[audio_input, interview_state],
|
| 472 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
)
|
| 474 |
-
|
| 475 |
# Next Question
|
| 476 |
next_question_btn.click(
|
| 477 |
fn=next_question,
|
| 478 |
inputs=[interview_state],
|
| 479 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 480 |
)
|
| 481 |
-
|
| 482 |
# Submit Interview (Placeholder for evaluation trigger)
|
| 483 |
submit_interview_btn.click(
|
| 484 |
fn=submit_interview,
|
|
|
|
| 245 |
except Exception as e:
|
| 246 |
return f"Error processing file: {str(e)}", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), None
|
| 247 |
|
| 248 |
+
# In PrepGenie/app.py, replace the existing start_interview function with this:
|
| 249 |
+
|
| 250 |
def start_interview(roles, processed_resume_data):
|
| 251 |
"""Starts the interview process."""
|
| 252 |
if not roles or not processed_resume_data:
|
| 253 |
+
# Return initial/empty states for UI components
|
| 254 |
+
return (
|
| 255 |
+
"Please select a role and ensure resume is processed.",
|
| 256 |
+
"", # initial question
|
| 257 |
+
gr.update(visible=False), # audio_input
|
| 258 |
+
gr.update(visible=False), # submit_answer_btn
|
| 259 |
+
gr.update(visible=False), # next_question_btn
|
| 260 |
+
gr.update(visible=False), # submit_interview_btn
|
| 261 |
+
gr.update(visible=False), # feedback_display
|
| 262 |
+
gr.update(visible=False), # metrics_display
|
| 263 |
+
gr.update(visible=False), # question_display (redundant, but matches output count)
|
| 264 |
+
gr.update(visible=False), # answer_instructions
|
| 265 |
+
{} # interview_state (empty dict)
|
| 266 |
+
)
|
| 267 |
|
| 268 |
try:
|
| 269 |
questions = generate_questions(roles, processed_resume_data)
|
| 270 |
initial_question = questions[0] if questions else "Could you please introduce yourself?"
|
| 271 |
|
| 272 |
# Initialize state for the interview
|
| 273 |
+
interview_state_data = {
|
| 274 |
"questions": questions,
|
| 275 |
"current_q_index": 0,
|
| 276 |
"answers": [],
|
|
|
|
| 280 |
"resume_data": processed_resume_data
|
| 281 |
}
|
| 282 |
|
| 283 |
+
# Return values matching the outputs list for start_interview_btn.click
|
| 284 |
return (
|
| 285 |
"Interview started. Please answer the first question.",
|
| 286 |
initial_question,
|
| 287 |
+
gr.update(visible=True), # audio_input visible
|
| 288 |
+
gr.update(visible=True), # submit_answer_btn visible
|
| 289 |
+
gr.update(visible=True), # next_question_btn visible
|
| 290 |
+
gr.update(visible=False), # submit_interview_btn hidden initially
|
| 291 |
+
gr.update(visible=False), # feedback_display hidden initially
|
| 292 |
+
gr.update(visible=False), # metrics_display hidden initially
|
| 293 |
+
gr.update(visible=True), # question_display visible
|
| 294 |
+
gr.update(visible=True), # answer_instructions visible
|
| 295 |
+
interview_state_data # Update the interview_state object
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
)
|
| 297 |
except Exception as e:
|
| 298 |
+
error_msg = f"Error starting interview: {str(e)}"
|
| 299 |
+
print(error_msg) # Log the error
|
| 300 |
+
return (
|
| 301 |
+
error_msg,
|
| 302 |
+
"", # No question
|
| 303 |
+
gr.update(visible=False), # Hide components
|
| 304 |
+
gr.update(visible=False),
|
| 305 |
+
gr.update(visible=False),
|
| 306 |
+
gr.update(visible=False),
|
| 307 |
+
gr.update(visible=False),
|
| 308 |
+
gr.update(visible=False),
|
| 309 |
+
gr.update(visible=False), # question_display
|
| 310 |
+
gr.update(visible=False), # answer_instructions
|
| 311 |
+
{} # Empty state on error
|
| 312 |
+
)
|
| 313 |
def submit_answer(audio, interview_state):
|
| 314 |
"""Handles submitting an answer via audio."""
|
| 315 |
if not audio or not interview_state:
|
|
|
|
| 475 |
|
| 476 |
# --- Event Listeners ---
|
| 477 |
|
|
|
|
| 478 |
process_btn.click(
|
| 479 |
fn=process_resume,
|
| 480 |
inputs=[file_upload],
|
| 481 |
+
outputs=[
|
| 482 |
+
file_status, role_selection, start_interview_btn,
|
| 483 |
+
question_display, answer_instructions, audio_input,
|
| 484 |
+
submit_answer_btn, next_question_btn, submit_interview_btn,
|
| 485 |
+
answer_display, feedback_display, metrics_display,
|
| 486 |
+
processed_resume_data # Pass processed data for next step
|
| 487 |
+
]
|
| 488 |
)
|
| 489 |
|
| 490 |
# Start Interview
|
| 491 |
start_interview_btn.click(
|
| 492 |
fn=start_interview,
|
| 493 |
inputs=[role_selection, processed_resume_data],
|
| 494 |
+
outputs=[
|
| 495 |
+
file_status, # Status message
|
| 496 |
+
question_display, # First question text
|
| 497 |
+
audio_input, # Audio input visibility
|
| 498 |
+
submit_answer_btn, # Submit Answer button visibility
|
| 499 |
+
next_question_btn, # Next Question button visibility
|
| 500 |
+
submit_interview_btn, # Submit Interview button visibility (initially hidden)
|
| 501 |
+
feedback_display, # Feedback textbox (initially hidden/empty)
|
| 502 |
+
metrics_display, # Metrics display (initially hidden/empty)
|
| 503 |
+
question_display, # (Duplicate reference, likely not needed, but kept for structure)
|
| 504 |
+
answer_instructions, # Answer instructions visibility
|
| 505 |
+
interview_state # THE KEY CHANGE: Update the entire state object
|
| 506 |
+
]
|
| 507 |
)
|
| 508 |
|
| 509 |
+
|
| 510 |
+
|
| 511 |
# Submit Answer
|
| 512 |
submit_answer_btn.click(
|
| 513 |
fn=submit_answer,
|
| 514 |
inputs=[audio_input, interview_state],
|
| 515 |
+
outputs=[
|
| 516 |
+
file_status, answer_display, interview_state,
|
| 517 |
+
feedback_display, feedback_display, # Update value and visibility
|
| 518 |
+
metrics_display, metrics_display, # Update value and visibility
|
| 519 |
+
audio_input, submit_answer_btn, next_question_btn,
|
| 520 |
+
submit_interview_btn, question_display, answer_instructions
|
| 521 |
+
]
|
| 522 |
)
|
| 523 |
+
|
| 524 |
# Next Question
|
| 525 |
next_question_btn.click(
|
| 526 |
fn=next_question,
|
| 527 |
inputs=[interview_state],
|
| 528 |
+
outputs=[
|
| 529 |
+
file_status, question_display, interview_state,
|
| 530 |
+
audio_input, submit_answer_btn, next_question_btn,
|
| 531 |
+
feedback_display, metrics_display, submit_interview_btn,
|
| 532 |
+
question_display, answer_instructions,
|
| 533 |
+
answer_display, metrics_display # Clear previous answer/metrics display
|
| 534 |
+
]
|
| 535 |
)
|
| 536 |
+
|
| 537 |
# Submit Interview (Placeholder for evaluation trigger)
|
| 538 |
submit_interview_btn.click(
|
| 539 |
fn=submit_interview,
|