Nazari11221 commited on
Commit
1e44e76
·
verified ·
1 Parent(s): 48e5b8d

Update app.py

Browse files

import os
import gradio as gr
import openai
import whisper
from gtts import gTTS
from fpdf import FPDF
import pandas as pd
import time

# 🔐 Set your OpenAI API key securely from environment variables
openai.api_key = os.environ.get("OPENAI_API_KEY")

# 🎙️ Load Whisper ASR model
model = whisper.load_model("base")

# 📁 CSV log file
LOG_FILE = "toefl_logs.csv"
if not os.path.exists(LOG_FILE):
pd.DataFrame(columns=["timestamp", "prompt", "transcript", "feedback"]).to_csv(LOG_FILE, index=False)

# 📝 TOEFL speaking prompts
prompts = [
"Do you agree or disagree with the idea that people learn more from failure than from success?",
"Some people believe that couples should live together before marriage. Do you agree or disagree?",
"Describe a teacher who has greatly influenced your life. What qualities did they have?"
]

# 🌐 Translations for multilingual UI labels
translations = {
"English": {
"audio_label": "Audio Feedback",
"pdf_label": "Download PDF",
"share_label": "Share App",
"feedback_history": "📜 Feedback History",
"record_label": "🎤 Record your answer",
"prompt_label": "📝 Choose a TOEFL Prompt",
"language_label": "🌐 Language",
"submit_label": "✅ Submit",
"share_button_label": "🔗 Share App",
"transcript_label": "🗣️ Your Transcript",
"feedback_label": "✅ AI Feedback",
},
"Pashto": {
"audio_label": "د فېډبک آډیو",
"pdf_label": "د فېډبک PDF",
"share_label": "اپ شریک کړئ",
"feedback_history": "د بیاکتنې تاریخ",
"record_label": "🎤 خپل ځواب ثبت کړئ",
"prompt_label": "📝 د TOEFL موضوع غوره کړئ",
"language_label": "🌐 ژبه",
"submit_label": "✅ وړاندې کول",
"share_button_label": "🔗 اپ شریک کړئ",
"transcript_label": "🗣️ ستاسو متن",
"feedback_label": "✅ AI فیډبیک",
},
"Dari": {
"audio_label": "صدای بازخورد",
"pdf_label": "دانلود PDF بازخورد",
"share_label": "اشتراک اپلیکیشن",
"feedback_history": "تاریخچه بازخورد",
"record_label": "🎤 پاسخ خود را ضبط کنید",
"prompt_label": "📝 یک موضوع TOEFL انتخاب کنید",
"language_label": "🌐 زبان",
"submit_label": "✅ ارسال",
"share_button_label": "🔗 اشتراک اپ",
"transcript_label": "🗣️ متن شما",
"feedback_label": "✅ بازخورد AI",
}
}

# 🎯 Transcribe audio file to text
def transcribe(audio):
result = model.transcribe(audio)
return result["text"]

# 🤖 Generate GPT feedback and score
def get_feedback(prompt, response):
full_prompt = f"""You are an English teacher scoring TOEFL Speaking responses.
Prompt: "{prompt}"
Student response: "{response}"
Give detailed, kind feedback and a score out of 4.
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": full_prompt}]
)
return completion.choices[0].message.content.strip()

# 🔉 Generate TTS audio for feedback text
def generate_audio_feedback(text):
tts = gTTS(text)
path = f"feedback_{int(time.time())}.mp3"
tts.save(path)
return path

# 📄 Create a PDF with prompt, transcript, and feedback
def generate_pdf(prompt, transcript, feedback):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.multi_cell(0, 10, f"Prompt:\n{prompt}\n\nYour Response:\n{transcript}\n\nFeedback:\n{feedback}")
path = f"feedback_{int(time.time())}.pdf"
pdf.output(path)
return path

# 🧠 Main function triggered by Gradio
def toefl_app(audio, selected_prompt, lang):
transcript = transcribe(audio)
feedback = get_feedback(selected_prompt, transcript)
audio_path = generate_audio_feedback(feedback)
pdf_path = generate_pdf(selected_prompt, transcript, feedback)

# Log response to CSV
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
log_df = pd.read_csv(LOG_FILE)
log_df.loc[len(log_df)] = [timestamp, selected_prompt, transcript, feedback]
log_df.to_csv(LOG_FILE, index=False)

labels = translations[lang]
return (
transcript,
feedback,
labels["audio_label"],
audio_path,
labels["pdf_label"],
pdf_path,
START_BEEP,
STOP_BEEP
)

# 📜 Show last 20 feedback history entries
def view_history():
df = pd.read_csv(LOG_FILE)
return df.tail(20).to_markdown()

# Update UI labels on language change
def update_ui_labels(lang):
labels = translations[lang]
return (
labels["record_label"],
labels["prompt_label"],
labels["language_label"],
labels["submit_label"],
labels["share_button_label"],
labels["transcript_label"],
labels["feedback_label"],
labels["audio_label"],
labels["pdf_label"],
labels["feedback_history"],
)

# 🌍 Language options for UI
lang_options = list(translations.keys())

# Beep sounds (upload these mp3 files to your repo)
START_BEEP = "start_beep.mp3"
STOP_BEEP = "stop_beep.mp3"

# 📱 Gradio UI
with gr.Blocks(css="""
footer {display: none !important;}
.gradio-container {
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
button, .gr-button {
font-size: 1.1em;
padding: 0.7em 1.2em;
}
""") as demo:
gr.Markdown("## 🗣️ TOEFL Speaking Practice Tool | [by @Nazari11221 ](https://huggingface.co/Nazari11221)")

with gr.Row():
audio = gr.Audio(type="filepath", label=translations["English"]["record_label"])
prompt = gr.Dropdown(prompts, label=translations["English"]["prompt_label"])
lang = gr.Dropdown(lang_options, value="English", label=translations["English"]["language_label"])

with gr.Row():
submit = gr.Button(translations["English"]["submit_label"])
share = gr.Button(translations["English"]["share_button_label"])

transcript = gr.Textbox(label=translations["English"]["transcript_label"])
feedback = gr.Textbox(label=translations["English"]["feedback_label"])
audio_label = gr.Label(value=translations["English"]["audio_label"])
audio_out = gr.Audio()
pdf_label = gr.Label(value=translations["English"]["pdf_label"])
pdf_out = gr.File()

beep_start = gr.Audio(START_BEEP, visible=False, autoplay=True)
beep_end = gr.Audio(STOP_BEEP, visible=False, autoplay=True)

with gr.Accordion(translations["English"]["feedback_history"], open=False) as feedback_history:
hist_output = gr.Markdown()
hist_btn = gr.Button("🔄 Refresh History")

# Connect buttons and events
submit.click(
toefl_app,
inputs=[audio, prompt, lang],
outputs=[transcript, feedback, audio_label, audio_out, pdf_label, pdf_out, beep_start, beep_end],
)
hist_btn.click(view_history, outputs=hist_output)
share.click(lambda: "🔗 Share this link: https://nazari11221-toefl-speaking-practice.hf.space", outputs=share)

# Update all UI labels when language changes
lang.change(
update_ui_labels,
inputs=[lang],
outputs=[audio, prompt, lang, submit, share, transcript, feedback, audio_label, pdf_label, feedback_history]
)

if __name__ == "__main__":
demo.launch()
![M.EWAZNAZARI TOEFL.png](https://cdn-uploads.huggingface.co/production/uploads/68722c688176b9e18629fdae/53hdSszsyFU-1SzS_CRBw.png)

Files changed (1) hide show
  1. app.py +73 -16
app.py CHANGED
@@ -31,19 +31,40 @@ translations = {
31
  "audio_label": "Audio Feedback",
32
  "pdf_label": "Download PDF",
33
  "share_label": "Share App",
34
- "feedback_history": "📜 Feedback History"
 
 
 
 
 
 
 
35
  },
36
  "Pashto": {
37
  "audio_label": "د فېډبک آډیو",
38
  "pdf_label": "د فېډبک PDF",
39
  "share_label": "اپ شریک کړئ",
40
- "feedback_history": "د بیاکتنې تاریخ"
 
 
 
 
 
 
 
41
  },
42
  "Dari": {
43
  "audio_label": "صدای بازخورد",
44
  "pdf_label": "دانلود PDF بازخورد",
45
  "share_label": "اشتراک اپلیکیشن",
46
- "feedback_history": "تاریخچه بازخورد"
 
 
 
 
 
 
 
47
  }
48
  }
49
 
@@ -103,6 +124,8 @@ def toefl_app(audio, selected_prompt, lang):
103
  audio_path,
104
  labels["pdf_label"],
105
  pdf_path,
 
 
106
  )
107
 
108
  # 📜 Show last 20 feedback history entries
@@ -110,6 +133,22 @@ def view_history():
110
  df = pd.read_csv(LOG_FILE)
111
  return df.tail(20).to_markdown()
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  # 🌍 Language options for UI
114
  lang_options = list(translations.keys())
115
 
@@ -118,40 +157,58 @@ START_BEEP = "start_beep.mp3"
118
  STOP_BEEP = "stop_beep.mp3"
119
 
120
  # 📱 Gradio UI
121
- with gr.Blocks(css="footer {display: none !important}") as demo:
 
 
 
 
 
 
 
 
 
 
 
122
  gr.Markdown("## 🗣️ TOEFL Speaking Practice Tool | [by @Nazari11221](https://huggingface.co/Nazari11221)")
123
 
124
  with gr.Row():
125
- audio = gr.Audio(type="filepath", label="🎤 Record your answer")
126
- prompt = gr.Dropdown(prompts, label="📝 Choose a TOEFL Prompt")
127
- lang = gr.Dropdown(lang_options, label="🌐 Language")
128
 
129
  with gr.Row():
130
- submit = gr.Button("✅ Submit")
131
- share = gr.Button("🔗 Share App")
132
 
133
- transcript = gr.Textbox(label="🗣️ Your Transcript")
134
- feedback = gr.Textbox(label="✅ AI Feedback")
135
- audio_label = gr.Label()
136
  audio_out = gr.Audio()
137
- pdf_label = gr.Label()
138
  pdf_out = gr.File()
139
 
140
  beep_start = gr.Audio(START_BEEP, visible=False, autoplay=True)
141
  beep_end = gr.Audio(STOP_BEEP, visible=False, autoplay=True)
142
 
143
- with gr.Accordion("📜 Feedback History", open=False):
144
  hist_output = gr.Markdown()
145
  hist_btn = gr.Button("🔄 Refresh History")
146
 
147
- # Connect buttons
148
  submit.click(
149
  toefl_app,
150
  inputs=[audio, prompt, lang],
151
- outputs=[transcript, feedback, audio_label, audio_out, pdf_label, pdf_out],
152
  )
153
  hist_btn.click(view_history, outputs=hist_output)
154
  share.click(lambda: "🔗 Share this link: https://nazari11221-toefl-speaking-practice.hf.space", outputs=share)
155
 
 
 
 
 
 
 
 
156
  if __name__ == "__main__":
157
  demo.launch()
 
31
  "audio_label": "Audio Feedback",
32
  "pdf_label": "Download PDF",
33
  "share_label": "Share App",
34
+ "feedback_history": "📜 Feedback History",
35
+ "record_label": "🎤 Record your answer",
36
+ "prompt_label": "📝 Choose a TOEFL Prompt",
37
+ "language_label": "🌐 Language",
38
+ "submit_label": "✅ Submit",
39
+ "share_button_label": "🔗 Share App",
40
+ "transcript_label": "🗣️ Your Transcript",
41
+ "feedback_label": "✅ AI Feedback",
42
  },
43
  "Pashto": {
44
  "audio_label": "د فېډبک آډیو",
45
  "pdf_label": "د فېډبک PDF",
46
  "share_label": "اپ شریک کړئ",
47
+ "feedback_history": "د بیاکتنې تاریخ",
48
+ "record_label": "🎤 خپل ځواب ثبت کړئ",
49
+ "prompt_label": "📝 د TOEFL موضوع غوره کړئ",
50
+ "language_label": "🌐 ژبه",
51
+ "submit_label": "✅ وړاندې کول",
52
+ "share_button_label": "🔗 اپ شریک کړئ",
53
+ "transcript_label": "🗣️ ستاسو متن",
54
+ "feedback_label": "✅ AI فیډبیک",
55
  },
56
  "Dari": {
57
  "audio_label": "صدای بازخورد",
58
  "pdf_label": "دانلود PDF بازخورد",
59
  "share_label": "اشتراک اپلیکیشن",
60
+ "feedback_history": "تاریخچه بازخورد",
61
+ "record_label": "🎤 پاسخ خود را ضبط کنید",
62
+ "prompt_label": "📝 یک موضوع TOEFL انتخاب کنید",
63
+ "language_label": "🌐 زبان",
64
+ "submit_label": "✅ ارسال",
65
+ "share_button_label": "🔗 اشتراک اپ",
66
+ "transcript_label": "🗣️ متن شما",
67
+ "feedback_label": "✅ بازخورد AI",
68
  }
69
  }
70
 
 
124
  audio_path,
125
  labels["pdf_label"],
126
  pdf_path,
127
+ START_BEEP,
128
+ STOP_BEEP
129
  )
130
 
131
  # 📜 Show last 20 feedback history entries
 
133
  df = pd.read_csv(LOG_FILE)
134
  return df.tail(20).to_markdown()
135
 
136
+ # Update UI labels on language change
137
+ def update_ui_labels(lang):
138
+ labels = translations[lang]
139
+ return (
140
+ labels["record_label"],
141
+ labels["prompt_label"],
142
+ labels["language_label"],
143
+ labels["submit_label"],
144
+ labels["share_button_label"],
145
+ labels["transcript_label"],
146
+ labels["feedback_label"],
147
+ labels["audio_label"],
148
+ labels["pdf_label"],
149
+ labels["feedback_history"],
150
+ )
151
+
152
  # 🌍 Language options for UI
153
  lang_options = list(translations.keys())
154
 
 
157
  STOP_BEEP = "stop_beep.mp3"
158
 
159
  # 📱 Gradio UI
160
+ with gr.Blocks(css="""
161
+ footer {display: none !important;}
162
+ .gradio-container {
163
+ max-width: 600px;
164
+ margin-left: auto;
165
+ margin-right: auto;
166
+ }
167
+ button, .gr-button {
168
+ font-size: 1.1em;
169
+ padding: 0.7em 1.2em;
170
+ }
171
+ """) as demo:
172
  gr.Markdown("## 🗣️ TOEFL Speaking Practice Tool | [by @Nazari11221](https://huggingface.co/Nazari11221)")
173
 
174
  with gr.Row():
175
+ audio = gr.Audio(type="filepath", label=translations["English"]["record_label"])
176
+ prompt = gr.Dropdown(prompts, label=translations["English"]["prompt_label"])
177
+ lang = gr.Dropdown(lang_options, value="English", label=translations["English"]["language_label"])
178
 
179
  with gr.Row():
180
+ submit = gr.Button(translations["English"]["submit_label"])
181
+ share = gr.Button(translations["English"]["share_button_label"])
182
 
183
+ transcript = gr.Textbox(label=translations["English"]["transcript_label"])
184
+ feedback = gr.Textbox(label=translations["English"]["feedback_label"])
185
+ audio_label = gr.Label(value=translations["English"]["audio_label"])
186
  audio_out = gr.Audio()
187
+ pdf_label = gr.Label(value=translations["English"]["pdf_label"])
188
  pdf_out = gr.File()
189
 
190
  beep_start = gr.Audio(START_BEEP, visible=False, autoplay=True)
191
  beep_end = gr.Audio(STOP_BEEP, visible=False, autoplay=True)
192
 
193
+ with gr.Accordion(translations["English"]["feedback_history"], open=False) as feedback_history:
194
  hist_output = gr.Markdown()
195
  hist_btn = gr.Button("🔄 Refresh History")
196
 
197
+ # Connect buttons and events
198
  submit.click(
199
  toefl_app,
200
  inputs=[audio, prompt, lang],
201
+ outputs=[transcript, feedback, audio_label, audio_out, pdf_label, pdf_out, beep_start, beep_end],
202
  )
203
  hist_btn.click(view_history, outputs=hist_output)
204
  share.click(lambda: "🔗 Share this link: https://nazari11221-toefl-speaking-practice.hf.space", outputs=share)
205
 
206
+ # Update all UI labels when language changes
207
+ lang.change(
208
+ update_ui_labels,
209
+ inputs=[lang],
210
+ outputs=[audio, prompt, lang, submit, share, transcript, feedback, audio_label, pdf_label, feedback_history]
211
+ )
212
+
213
  if __name__ == "__main__":
214
  demo.launch()