ankban commited on
Commit
c369adb
Β·
verified Β·
1 Parent(s): 8fa2b4c

Completely update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -96
app.py CHANGED
@@ -1,109 +1,98 @@
1
  import gradio as gr
 
2
  import os
3
  import uuid
4
- from faster_whisper import WhisperModel
5
  from gtts import gTTS
 
6
  import subprocess
7
- import openai
8
- from openai import OpenAI
9
  import shutil
10
 
11
- # Use writable cache for Hugging Face
12
- os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
 
 
 
 
 
 
 
 
 
 
 
13
  os.environ["HF_HOME"] = "/tmp/hf"
14
  os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf"
15
  os.environ["XDG_CACHE_HOME"] = "/tmp/hf"
16
 
17
- chatter_owl_url = "file/images/chatter_owl.png"
18
-
19
- # Load Whisper and set OpenAI key
20
- model = WhisperModel("base", compute_type="int8") # Fastest CPU option
21
  openai.api_key = os.getenv("OPENAI_API_KEY")
22
 
23
- # Prompt template
24
- PROMPT_TEMPLATE = """
25
- You are a communication coach evaluating a user's spoken response.
26
-
27
- Evaluate the speech using these 5 dimensions:
28
- 1. Clarity
29
- 2. Structure
30
- 3. Fluency
31
- 4. Content Relevance
32
- 5. Tone & Expression
33
-
34
- For each:
35
- - Score from 0–10
36
- - Provide brief, specific feedback
37
-
38
- Then:
39
- - Give an overall 3–4 line summary
40
- - End with a motivational sentence
41
-
42
- Lastly:
43
- - Provide an improved version of the speech that better demonstrates effective communication, based on their original transcript.
44
-
45
- Transcript:
46
- \"\"\"{transcript}\"\"\"
47
- """
48
-
49
- # Convert uploaded audio to 16kHz mono WAV
50
  def convert_to_wav(input_file):
51
  output_wav = f"/tmp/{uuid.uuid4()}.wav"
52
  command = ["ffmpeg", "-y", "-i", input_file, "-ar", "16000", "-ac", "1", output_wav]
53
  subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
54
  return output_wav
55
 
56
- # Call GPT to analyze transcript
57
- client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
58
-
59
- def generate_feedback_with_llm(transcript):
60
- prompt = PROMPT_TEMPLATE.format(transcript=transcript.strip())
61
-
62
- response = client.chat.completions.create(
63
- model="gpt-4",
64
- messages=[
65
- {"role": "system", "content": "You are a communication coach that gives structured and emotionally aware feedback."},
66
- {"role": "user", "content": prompt}
67
- ],
68
- temperature=0.7
69
- )
70
-
71
- return response.choices[0].message.content
72
-
73
  def transcribe_audio(audio_path):
74
  segments, info = model.transcribe(audio_path)
75
- transcript = " ".join([segment.text for segment in segments])
76
- return transcript
77
-
78
- # Main function
79
- def tutor_feedback(audio_file):
80
- if not audio_file or not os.path.exists(audio_file):
81
- return "No audio received.", "Please upload or record again.", None
82
 
83
- print(f">>> Audio received: {audio_file}")
84
- print(f">>> File size: {os.path.getsize(audio_file)} bytes")
85
-
86
- # Convert to whisper-friendly WAV
87
- wav_path = convert_to_wav(audio_file)
88
-
89
- # Transcribe
90
- transcript = transcribe_audio(wav_path)
91
 
 
 
 
 
 
 
92
 
93
- # Feedback via GPT
94
- feedback_text = generate_feedback_with_llm(transcript)
 
95
 
96
- # TTS
97
- tts = gTTS(feedback_text)
98
- mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
99
- tts.save(mp3_path)
100
 
101
- return transcript, feedback_text, mp3_path
 
 
 
 
 
 
 
 
 
 
 
102
 
103
- # Generate example version of the same speech
104
- def generate_example_response(transcript):
105
  prompt = f"""
106
- You are a communication tutor. Rewrite this speech transcript to be a more polished and confident version, while keeping the meaning and tone similar.
107
 
108
  Transcript:
109
  {transcript}
@@ -118,30 +107,40 @@ Transcript:
118
  )
119
  return response["choices"][0]["message"]["content"]
120
 
121
- # Hook up logic
122
- def show_example_feedback(transcript):
123
- # Extract only example portion from GPT or return a pre-generated version
124
- return generate_example_response(transcript)
125
 
126
- # Gradio interface
127
- # Path to your CSS file
128
- css_path = "light_mode_chatter_owl.css" # Make sure this file is in the same directory as app.py
129
 
130
- # Path to your CSS file
131
- css_path = "light_mode_chatter_owl.css" # Make sure this file is in the same directory as app.py
 
 
132
 
133
- # App UI
 
 
134
  with gr.Blocks(css="light_mode_chatter_owl.css") as app:
135
  gr.Markdown(
136
  """
137
  <div id="header" style="text-align: center;">
138
  <img src="file/images/chatter_owl.png" width="120">
139
  <h2>πŸ¦‰ Meet <strong>Chatter the Owl</strong></h2>
140
- <p>Speak into the mic, and I’ll give you structured feedback to help you grow as a communicator!</p>
141
  </div>
142
  """
143
  )
144
 
 
 
 
 
 
 
145
  with gr.Row():
146
  audio_input = gr.Audio(type="filepath", label="πŸŽ™ Speak or Upload Audio")
147
 
@@ -156,16 +155,26 @@ with gr.Blocks(css="light_mode_chatter_owl.css") as app:
156
 
157
  example_box = gr.Textbox(label="πŸ—£ Suggested Improvement", visible=False)
158
 
159
- # Interactions
160
- audio_input.change(fn=tutor_feedback, inputs=audio_input,
161
- outputs=[transcript_box, feedback_box, audio_output, hidden_transcript])
162
-
163
- try_again.click(fn=lambda: ("", "", None, "", ""), inputs=None,
164
- outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, example_box])
165
 
166
- show_example.click(fn=generate_example_response, inputs=hidden_transcript, outputs=example_box)
 
 
 
 
167
 
 
 
 
 
 
168
 
 
169
  if __name__ == "__main__":
170
  print("βœ… App is launching...")
171
  app.launch(server_name="0.0.0.0", server_port=7860, debug=True)
 
1
  import gradio as gr
2
+ import openai
3
  import os
4
  import uuid
 
5
  from gtts import gTTS
6
+ from faster_whisper import WhisperModel
7
  import subprocess
 
 
8
  import shutil
9
 
10
+ # === Clean /tmp at startup ===
11
+ TMP_DIR = "/tmp"
12
+ for sub in os.listdir(TMP_DIR):
13
+ sub_path = os.path.join(TMP_DIR, sub)
14
+ try:
15
+ if os.path.isfile(sub_path) or os.path.islink(sub_path):
16
+ os.unlink(sub_path)
17
+ elif os.path.isdir(sub_path):
18
+ shutil.rmtree(sub_path)
19
+ except Exception as e:
20
+ print(f"Failed to delete {sub_path}. Reason: {e}")
21
+
22
+ # === Environment Setup ===
23
  os.environ["HF_HOME"] = "/tmp/hf"
24
  os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf"
25
  os.environ["XDG_CACHE_HOME"] = "/tmp/hf"
26
 
27
+ # Use writable cache for Hugging Face
28
+ os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
 
 
29
  openai.api_key = os.getenv("OPENAI_API_KEY")
30
 
31
+ # === Language Codes for GPT + TTS ===
32
+ LANG_CODES = {
33
+ "English": "en",
34
+ "Spanish": "es",
35
+ "Hindi": "hi",
36
+ "French": "fr",
37
+ "German": "de",
38
+ "Arabic": "ar",
39
+ "Chinese": "zh",
40
+ "Portuguese": "pt",
41
+ "Japanese": "ja",
42
+ "Korean": "ko"
43
+ }
44
+
45
+ # === Load Whisper Model ===
46
+ model = WhisperModel("base", compute_type="int8")
47
+
48
+ # === Audio Processing ===
 
 
 
 
 
 
 
 
 
49
  def convert_to_wav(input_file):
50
  output_wav = f"/tmp/{uuid.uuid4()}.wav"
51
  command = ["ffmpeg", "-y", "-i", input_file, "-ar", "16000", "-ac", "1", output_wav]
52
  subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
53
  return output_wav
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  def transcribe_audio(audio_path):
56
  segments, info = model.transcribe(audio_path)
57
+ return " ".join([segment.text for segment in segments])
 
 
 
 
 
 
58
 
59
+ # === GPT-4 Feedback Generation ===
60
+ def generate_feedback(transcript, language):
61
+ prompt = f"""
62
+ You are a communication coach. Please respond in [language={language}].
 
 
 
 
63
 
64
+ Evaluate the user's speech on:
65
+ 1. Clarity
66
+ 2. Structure
67
+ 3. Fluency
68
+ 4. Content Relevance
69
+ 5. Tone & Expression
70
 
71
+ Each category:
72
+ - Score out of 10
73
+ - Short explanation
74
 
75
+ End with:
76
+ - Overall feedback summary
77
+ - One motivational line
 
78
 
79
+ Transcript:
80
+ {transcript}
81
+ """
82
+ response = openai.ChatCompletion.create(
83
+ model="gpt-4",
84
+ messages=[
85
+ {"role": "system", "content": f"You are a supportive communication coach responding in {language}."},
86
+ {"role": "user", "content": prompt}
87
+ ],
88
+ temperature=0.7
89
+ )
90
+ return response["choices"][0]["message"]["content"]
91
 
92
+ # === GPT-4 Suggested Example ===
93
+ def generate_example_response(transcript, language):
94
  prompt = f"""
95
+ You are a communication tutor. Rewrite this speech transcript to be a more polished and confident version, while keeping the meaning and tone similar. Respond in {language}.
96
 
97
  Transcript:
98
  {transcript}
 
107
  )
108
  return response["choices"][0]["message"]["content"]
109
 
110
+ # === Main Feedback Function ===
111
+ def tutor_feedback(audio_file, language):
112
+ if not audio_file or not os.path.exists(audio_file):
113
+ return "", "No audio received.", None, ""
114
 
115
+ wav_path = convert_to_wav(audio_file)
116
+ transcript = transcribe_audio(wav_path)
117
+ feedback_text = generate_feedback(transcript, language)
118
 
119
+ lang_code = LANG_CODES.get(language, "en")
120
+ tts = gTTS(feedback_text, lang=lang_code)
121
+ mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
122
+ tts.save(mp3_path)
123
 
124
+ return transcript, feedback_text, mp3_path, transcript
125
+
126
+ # === Gradio Interface ===
127
  with gr.Blocks(css="light_mode_chatter_owl.css") as app:
128
  gr.Markdown(
129
  """
130
  <div id="header" style="text-align: center;">
131
  <img src="file/images/chatter_owl.png" width="120">
132
  <h2>πŸ¦‰ Meet <strong>Chatter the Owl</strong></h2>
133
+ <p>Choose your language, speak into the mic, and I’ll give you structured feedback to help you grow as a communicator!</p>
134
  </div>
135
  """
136
  )
137
 
138
+ language_dropdown = gr.Dropdown(
139
+ label="🌍 Select Your Language",
140
+ choices=list(LANG_CODES.keys()),
141
+ value="English"
142
+ )
143
+
144
  with gr.Row():
145
  audio_input = gr.Audio(type="filepath", label="πŸŽ™ Speak or Upload Audio")
146
 
 
155
 
156
  example_box = gr.Textbox(label="πŸ—£ Suggested Improvement", visible=False)
157
 
158
+ # Connect functions
159
+ audio_input.change(
160
+ fn=tutor_feedback,
161
+ inputs=[audio_input, language_dropdown],
162
+ outputs=[transcript_box, feedback_box, audio_output, hidden_transcript]
163
+ )
164
 
165
+ try_again.click(
166
+ fn=lambda: ("", "", None, "", ""),
167
+ inputs=None,
168
+ outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, example_box]
169
+ )
170
 
171
+ show_example.click(
172
+ fn=generate_example_response,
173
+ inputs=[hidden_transcript, language_dropdown],
174
+ outputs=example_box
175
+ )
176
 
177
+ # === Launch App ===
178
  if __name__ == "__main__":
179
  print("βœ… App is launching...")
180
  app.launch(server_name="0.0.0.0", server_port=7860, debug=True)