ankban commited on
Commit
93a55cf
Β·
verified Β·
1 Parent(s): fee1ded

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -135
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import gradio as gr
2
  import openai
3
  from openai import OpenAI
@@ -7,21 +8,17 @@ from gtts import gTTS
7
  from faster_whisper import WhisperModel
8
  import subprocess
9
  import shutil
10
- import datetime
11
- import json
12
- import csv
13
-
14
- # === Clean /tmp at startup ===
15
- TMP_DIR = "/tmp"
16
- for sub in os.listdir(TMP_DIR):
17
- sub_path = os.path.join(TMP_DIR, sub)
18
- try:
19
- if os.path.isfile(sub_path) or os.path.islink(sub_path):
20
- os.unlink(sub_path)
21
- elif os.path.isdir(sub_path):
22
- shutil.rmtree(sub_path)
23
- except Exception as e:
24
- print(f"Failed to delete {sub_path}. Reason: {e}")
25
 
26
  # === Environment Setup ===
27
  os.environ["HF_HOME"] = "/tmp/hf"
@@ -29,40 +26,48 @@ os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf"
29
  os.environ["XDG_CACHE_HOME"] = "/tmp/hf"
30
  os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
31
  openai.api_key = os.getenv("OPENAI_API_KEY")
 
32
 
33
- # === Language Codes for GPT + TTS ===
34
  LANG_CODES = {
35
- "English": "en",
36
- "Spanish": "es",
37
- "Hindi": "hi",
38
- "French": "fr",
39
- "German": "de",
40
- "Arabic": "ar",
41
- "Chinese": "zh",
42
- "Portuguese": "pt",
43
- "Japanese": "ja",
44
- "Korean": "ko"
45
  }
46
 
47
- # === Load Whisper Model ===
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  model = WhisperModel("base", compute_type="int8")
49
- client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
50
-
51
- # === Persistent session history ===
52
- HISTORY_FILE = "history.json"
53
- def load_history():
54
- if os.path.exists(HISTORY_FILE):
55
- with open(HISTORY_FILE, "r", encoding="utf-8") as f:
56
- return json.load(f)
57
- return []
58
 
59
- def save_history(history):
60
- with open(HISTORY_FILE, "w", encoding="utf-8") as f:
61
- json.dump(history, f, ensure_ascii=False, indent=2)
62
-
63
- session_history = load_history()
64
-
65
- # === Audio Processing ===
66
  def convert_to_wav(input_file):
67
  output_wav = f"/tmp/{uuid.uuid4()}.wav"
68
  command = ["ffmpeg", "-y", "-i", input_file, "-ar", "16000", "-ac", "1", output_wav]
@@ -70,13 +75,12 @@ def convert_to_wav(input_file):
70
  return output_wav
71
 
72
  def transcribe_audio(audio_path):
73
- segments, info = model.transcribe(audio_path)
74
  return " ".join([segment.text for segment in segments])
75
 
76
- # === GPT-4 Feedback Generation ===
77
  def generate_feedback(transcript, language):
78
- prompt = f"""
79
- You are a communication coach. Please respond in [language={language}].
80
  Evaluate the user's speech on:
81
  1. Clarity
82
  2. Structure
@@ -102,11 +106,8 @@ Transcript:
102
  )
103
  return response.choices[0].message.content
104
 
105
- # === GPT-4 Suggested Example ===
106
  def generate_example_response(transcript, language):
107
- prompt = f"""
108
- You are a communication coach.
109
- Rewrite this speech to make it more polished, fluent, and confident.
110
  Keep the meaning and tone the same, but improve clarity and structure.
111
  Transcript:
112
  {transcript}
@@ -120,10 +121,9 @@ Transcript:
120
  )
121
  return response.choices[0].message.content
122
 
123
- # === Main Feedback Function ===
124
  def tutor_feedback(audio_file, language):
125
  if not audio_file or not os.path.exists(audio_file):
126
- return "", "No audio received.", None, ""
127
 
128
  wav_path = convert_to_wav(audio_file)
129
  transcript = transcribe_audio(wav_path)
@@ -134,47 +134,22 @@ def tutor_feedback(audio_file, language):
134
  mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
135
  tts.save(mp3_path)
136
 
137
- timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
138
- session_entry = {
139
- "timestamp": timestamp,
140
- "transcript": transcript,
141
- "feedback": feedback_text
142
- }
143
- session_history.append(session_entry)
144
- save_history(session_history)
145
-
146
- return transcript, feedback_text, mp3_path, transcript
147
-
148
- # === Export history ===
149
- def export_history_json():
150
- return json.dumps(session_history, indent=2, ensure_ascii=False)
151
-
152
- def export_history_csv():
153
- csv_path = "/tmp/session_history.csv"
154
- with open(csv_path, "w", newline='', encoding="utf-8") as f:
155
- writer = csv.writer(f)
156
- writer.writerow(["Timestamp", "Transcript", "Feedback"])
157
- for s in session_history:
158
- writer.writerow([s['timestamp'], s['transcript'], s['feedback']])
159
- return csv_path
160
 
161
  # === Gradio Interface ===
162
  with gr.Blocks(css="light_mode_chatter_owl.css") as app:
163
- gr.Markdown(
164
- """
165
- <div id="header" style="text-align: center;">
166
- <img src="file/images/chatter_owl.png" width="120">
167
- <h2>πŸ¦‰ Meet <strong>Chatter the Owl</strong></h2>
168
- <p>Choose your language, speak into the mic, and I’ll give you structured feedback to help you grow as a communicator!</p>
169
- </div>
170
- """
171
- )
172
 
173
- language_dropdown = gr.Dropdown(
174
- label="🌍 Select Your Language",
175
- choices=list(LANG_CODES.keys()),
176
- value="English"
177
- )
178
 
179
  with gr.Row():
180
  audio_input = gr.Audio(type="filepath", label="πŸŽ™ Speak or Upload Audio")
@@ -189,55 +164,22 @@ with gr.Blocks(css="light_mode_chatter_owl.css") as app:
189
  show_example = gr.Button("🎯 Show Me an Example")
190
 
191
  example_box = gr.Textbox(label="πŸ—£ Suggested Improvement", visible=True, placeholder="Click to generate improved speech...")
 
192
 
193
- def get_session_table():
194
- rows = [[s['timestamp'], s['transcript'][:60] + '...', s['feedback'][:60] + '...'] for s in session_history]
195
- return rows
196
-
197
- history_display = gr.Dataframe(headers=["πŸ•’ Timestamp", "πŸ“ Transcript", "πŸ“‹ Feedback Preview"], interactive=False)
198
- history_btn = gr.Button("πŸ•“ View My Past Sessions")
199
- export_json_btn = gr.Button("πŸ“€ Export History (JSON)")
200
- export_csv_btn = gr.Button("πŸ“„ Export History (CSV)")
201
- export_json_output = gr.Textbox(visible=False)
202
- export_csv_output = gr.File(label="Download CSV")
203
-
204
- audio_input.change(
205
- fn=tutor_feedback,
206
- inputs=[audio_input, language_dropdown],
207
- outputs=[transcript_box, feedback_box, audio_output, hidden_transcript]
208
- )
209
 
210
- try_again.click(
211
- fn=lambda: ("", "", None, "", ""),
212
- inputs=None,
213
- outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, example_box]
214
- )
215
 
216
- show_example.click(
217
- fn=generate_example_response,
218
- inputs=[hidden_transcript, language_dropdown],
219
- outputs=example_box
220
- )
221
-
222
- history_btn.click(
223
- fn=get_session_table,
224
- inputs=None,
225
- outputs=history_display
226
- )
227
-
228
- export_json_btn.click(
229
- fn=export_history_json,
230
- inputs=None,
231
- outputs=export_json_output
232
- )
233
-
234
- export_csv_btn.click(
235
- fn=export_history_csv,
236
- inputs=None,
237
- outputs=export_csv_output
238
- )
239
 
240
  # === Launch App ===
241
  if __name__ == "__main__":
242
  print("βœ… App is launching...")
243
- app.launch(server_name="0.0.0.0", server_port=7860, debug=True)
 
1
+
2
  import gradio as gr
3
  import openai
4
  from openai import OpenAI
 
8
  from faster_whisper import WhisperModel
9
  import subprocess
10
  import shutil
11
+ from datetime import datetime
12
+ from sqlmodel import SQLModel, Field, create_engine, Session, select
13
+
14
+ # === Clean safe app-generated temp files ===
15
+ import glob
16
+ for pattern in ["/tmp/*.wav", "/tmp/*.mp3"]:
17
+ for filepath in glob.glob(pattern):
18
+ try:
19
+ os.remove(filepath)
20
+ except Exception as e:
21
+ print(f"Could not delete {filepath}: {e}")
 
 
 
 
22
 
23
  # === Environment Setup ===
24
  os.environ["HF_HOME"] = "/tmp/hf"
 
26
  os.environ["XDG_CACHE_HOME"] = "/tmp/hf"
27
  os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
28
  openai.api_key = os.getenv("OPENAI_API_KEY")
29
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
30
 
31
+ # === Language Codes ===
32
  LANG_CODES = {
33
+ "English": "en", "Spanish": "es", "Hindi": "hi", "French": "fr", "German": "de",
34
+ "Arabic": "ar", "Chinese": "zh", "Portuguese": "pt", "Japanese": "ja", "Korean": "ko"
 
 
 
 
 
 
 
 
35
  }
36
 
37
+ # === SQLModel Setup ===
38
+ class SessionEntry(SQLModel, table=True):
39
+ id: int = Field(default=None, primary_key=True)
40
+ timestamp: str
41
+ transcript: str
42
+ feedback: str
43
+ language: str
44
+
45
+ db_path = "chatter_sessions.db"
46
+ engine = create_engine(f"sqlite:///{db_path}")
47
+ SQLModel.metadata.create_all(engine)
48
+
49
+ def save_to_db(transcript, feedback, language):
50
+ session = Session(engine)
51
+ entry = SessionEntry(
52
+ timestamp=datetime.now().strftime("%Y-%m-%d %H:%M"),
53
+ transcript=transcript,
54
+ feedback=feedback,
55
+ language=language
56
+ )
57
+ session.add(entry)
58
+ session.commit()
59
+ session.close()
60
+
61
+ def fetch_all_sessions():
62
+ session = Session(engine)
63
+ statement = select(SessionEntry)
64
+ results = session.exec(statement).all()
65
+ session.close()
66
+ return results
67
+
68
+ # === Load Whisper ===
69
  model = WhisperModel("base", compute_type="int8")
 
 
 
 
 
 
 
 
 
70
 
 
 
 
 
 
 
 
71
  def convert_to_wav(input_file):
72
  output_wav = f"/tmp/{uuid.uuid4()}.wav"
73
  command = ["ffmpeg", "-y", "-i", input_file, "-ar", "16000", "-ac", "1", output_wav]
 
75
  return output_wav
76
 
77
  def transcribe_audio(audio_path):
78
+ segments, _ = model.transcribe(audio_path)
79
  return " ".join([segment.text for segment in segments])
80
 
81
+ # === GPT Feedback ===
82
  def generate_feedback(transcript, language):
83
+ prompt = f"""You are a communication coach. Please respond in [language={language}].
 
84
  Evaluate the user's speech on:
85
  1. Clarity
86
  2. Structure
 
106
  )
107
  return response.choices[0].message.content
108
 
 
109
  def generate_example_response(transcript, language):
110
+ prompt = f"""You are a communication coach. Rewrite this speech to make it more polished, fluent, and confident.
 
 
111
  Keep the meaning and tone the same, but improve clarity and structure.
112
  Transcript:
113
  {transcript}
 
121
  )
122
  return response.choices[0].message.content
123
 
 
124
  def tutor_feedback(audio_file, language):
125
  if not audio_file or not os.path.exists(audio_file):
126
+ return "", "No audio received.", None, "", []
127
 
128
  wav_path = convert_to_wav(audio_file)
129
  transcript = transcribe_audio(wav_path)
 
134
  mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
135
  tts.save(mp3_path)
136
 
137
+ save_to_db(transcript, feedback_text, language)
138
+ sessions = fetch_all_sessions()
139
+
140
+ return transcript, feedback_text, mp3_path, transcript, [[s.timestamp, s.language, s.transcript[:40], s.feedback[:40]] for s in sessions]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
  # === Gradio Interface ===
143
  with gr.Blocks(css="light_mode_chatter_owl.css") as app:
144
+ gr.Markdown("""
145
+ <div id="header" style="text-align: center;">
146
+ <img src="file/images/chatter_owl.png" width="120">
147
+ <h2>πŸ¦‰ Meet <strong>Chatter the Owl</strong></h2>
148
+ <p>Choose your language, speak into the mic, and I’ll give you structured feedback to help you grow as a communicator!</p>
149
+ </div>
150
+ """)
 
 
151
 
152
+ language_dropdown = gr.Dropdown(label="🌍 Select Your Language", choices=list(LANG_CODES.keys()), value="English")
 
 
 
 
153
 
154
  with gr.Row():
155
  audio_input = gr.Audio(type="filepath", label="πŸŽ™ Speak or Upload Audio")
 
164
  show_example = gr.Button("🎯 Show Me an Example")
165
 
166
  example_box = gr.Textbox(label="πŸ—£ Suggested Improvement", visible=True, placeholder="Click to generate improved speech...")
167
+ history_table = gr.Dataframe(headers=["πŸ•’ Timestamp", "🌐 Language", "πŸ“ Transcript (Preview)", "πŸ“‹ Feedback (Preview)"])
168
 
169
+ # Interactions
170
+ audio_input.change(fn=tutor_feedback,
171
+ inputs=[audio_input, language_dropdown],
172
+ outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, history_table])
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
+ try_again.click(fn=lambda: ("", "", None, "", "", []),
175
+ inputs=None,
176
+ outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, example_box, history_table])
 
 
177
 
178
+ show_example.click(fn=generate_example_response,
179
+ inputs=[hidden_transcript, language_dropdown],
180
+ outputs=example_box)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
  # === Launch App ===
183
  if __name__ == "__main__":
184
  print("βœ… App is launching...")
185
+ app.launch(server_name="0.0.0.0", server_port=7860, debug=True)