husseinelsaadi commited on
Commit
fd40bd4
·
1 Parent(s): 3c4bd31
Files changed (1) hide show
  1. backend/routes/interview_api.py +42 -27
backend/routes/interview_api.py CHANGED
@@ -1,7 +1,7 @@
1
  import os
2
  import uuid
3
  import json
4
- from flask import Blueprint, request, jsonify, url_for
5
  from flask_login import login_required, current_user
6
  from backend.models.database import db, Job, Application
7
  from backend.services.interview_engine import (
@@ -35,20 +35,25 @@ def start_interview():
35
 
36
  question = generate_first_question(profile, job)
37
 
38
- # Create static/audio directory if it doesn't exist
39
- audio_dir = os.path.join("static", "audio")
 
 
 
 
40
  os.makedirs(audio_dir, exist_ok=True)
41
-
42
  audio_filename = f"q_{uuid.uuid4().hex}.wav"
43
  audio_path = os.path.join(audio_dir, audio_filename)
44
-
45
- # Generate audio
46
- edge_tts_to_file_sync(question, audio_path)
47
-
48
- return jsonify({
49
- "question": question,
50
- "audio_url": url_for("static", filename=f"audio/{audio_filename}")
51
- })
 
52
 
53
  @interview_api.route("/transcribe_audio", methods=["POST"])
54
  @login_required
@@ -57,10 +62,13 @@ def transcribe_audio():
57
  if not audio_file:
58
  return jsonify({"error": "No audio file received."}), 400
59
 
60
- # Create temp directory if it doesn't exist
61
- temp_dir = "temp"
 
 
 
62
  os.makedirs(temp_dir, exist_ok=True)
63
-
64
  filename = f"user_audio_{uuid.uuid4().hex}.wav"
65
  path = os.path.join(temp_dir, filename)
66
  audio_file.save(path)
@@ -82,26 +90,33 @@ def process_answer():
82
  answer = data.get("answer", "")
83
  question_idx = data.get("questionIndex", 0)
84
 
85
- # Generate next question (simplified for now)
86
- next_question = f"Follow-up question {question_idx + 2}: Can you elaborate on your experience with relevant technologies?"
87
-
88
- # Create audio for next question
89
- audio_dir = os.path.join("static", "audio")
 
 
90
  os.makedirs(audio_dir, exist_ok=True)
91
-
92
  audio_filename = f"q_{uuid.uuid4().hex}.wav"
93
  audio_path = os.path.join(audio_dir, audio_filename)
94
-
95
- edge_tts_to_file_sync(next_question, audio_path)
96
-
97
- return jsonify({
 
 
 
98
  "success": True,
99
  "nextQuestion": next_question,
100
- "audioUrl": url_for("static", filename=f"audio/{audio_filename}"),
101
  "evaluation": {
102
  "score": "medium",
103
  "feedback": "Good answer, but be more specific."
104
  },
105
  "isComplete": question_idx >= 2,
106
  "summary": []
107
- })
 
 
 
 
1
  import os
2
  import uuid
3
  import json
4
+ from flask import Blueprint, request, jsonify, url_for, current_app
5
  from flask_login import login_required, current_user
6
  from backend.models.database import db, Job, Application
7
  from backend.services.interview_engine import (
 
35
 
36
  question = generate_first_question(profile, job)
37
 
38
+ # Determine the static folder from the current app context. Flask serves
39
+ # files from ``current_app.static_folder`` and uses ``static_url_path``
40
+ # when generating URLs. If audio generation fails (for example because
41
+ # network access is unavailable), we simply omit the audio file and allow
42
+ # the frontend to fall back to text‑only mode.
43
+ audio_dir = os.path.join(current_app.static_folder, "audio")
44
  os.makedirs(audio_dir, exist_ok=True)
45
+
46
  audio_filename = f"q_{uuid.uuid4().hex}.wav"
47
  audio_path = os.path.join(audio_dir, audio_filename)
48
+
49
+ # Generate audio synchronously. The function returns None on error.
50
+ audio_out = edge_tts_to_file_sync(question, audio_path)
51
+
52
+ response = {"question": question}
53
+ if audio_out:
54
+ # Use url_for to build the URL relative to the configured static folder.
55
+ response["audio_url"] = url_for("static", filename=f"audio/{audio_filename}")
56
+ return jsonify(response)
57
 
58
  @interview_api.route("/transcribe_audio", methods=["POST"])
59
  @login_required
 
62
  if not audio_file:
63
  return jsonify({"error": "No audio file received."}), 400
64
 
65
+ # Create a temporary directory inside Flask's instance path. Using the
66
+ # instance path ensures that the folder is writable in environments like
67
+ # Hugging Face Spaces, where the working directory may be read‑only. The
68
+ # instance path is configured in ``app.py`` to point at ``/tmp/flask_instance``.
69
+ temp_dir = os.path.join(current_app.instance_path, "interview_temp")
70
  os.makedirs(temp_dir, exist_ok=True)
71
+
72
  filename = f"user_audio_{uuid.uuid4().hex}.wav"
73
  path = os.path.join(temp_dir, filename)
74
  audio_file.save(path)
 
90
  answer = data.get("answer", "")
91
  question_idx = data.get("questionIndex", 0)
92
 
93
+ # Generate next question (simplified for now). In a full implementation this
94
+ # would call a model such as groq_llm to generate a follow‑up question based
95
+ # on the candidate's answer.
96
+ next_question = f"Follow‑up question {question_idx + 2}: Can you elaborate on your experience with relevant technologies?"
97
+
98
+ # Prepare audio output directory inside the app's static folder
99
+ audio_dir = os.path.join(current_app.static_folder, "audio")
100
  os.makedirs(audio_dir, exist_ok=True)
101
+
102
  audio_filename = f"q_{uuid.uuid4().hex}.wav"
103
  audio_path = os.path.join(audio_dir, audio_filename)
104
+
105
+ # Attempt to generate speech for the next question. If audio generation
106
+ # fails, ``audio_out`` will be None and we simply omit ``audioUrl`` in
107
+ # the JSON response.
108
+ audio_out = edge_tts_to_file_sync(next_question, audio_path)
109
+
110
+ response = {
111
  "success": True,
112
  "nextQuestion": next_question,
 
113
  "evaluation": {
114
  "score": "medium",
115
  "feedback": "Good answer, but be more specific."
116
  },
117
  "isComplete": question_idx >= 2,
118
  "summary": []
119
+ }
120
+ if audio_out:
121
+ response["audioUrl"] = url_for("static", filename=f"audio/{audio_filename}")
122
+ return jsonify(response)