Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -11,34 +11,35 @@ p = pipeline("automatic-speech-recognition", model="jonatasgrosman/wav2vec2-larg
|
|
11 |
|
12 |
# Read excel file and store it in a dictionary
|
13 |
def read_excel_data(file_path, sheet_name):
|
14 |
-
|
|
|
15 |
try:
|
16 |
# Read the Excel file
|
17 |
df = pd.read_excel(file_path, sheet_name=sheet_name)
|
18 |
# Iterate over the rows
|
19 |
for index, row in df.iterrows():
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
28 |
except Exception as e:
|
29 |
print(f"Error reading Excel file: {e}")
|
30 |
-
|
31 |
-
|
32 |
# List of sample texts to read
|
33 |
excel_file_path = "ASR_live_test.xlsx"
|
34 |
-
sheet_name= 'sample_test'
|
35 |
choices = read_excel_data(excel_file_path, sheet_name)
|
36 |
|
37 |
# Similarity function
|
38 |
def similar(a, b):
|
39 |
return SequenceMatcher(None, a, b).ratio()
|
40 |
|
41 |
-
# Audio Transcription function
|
42 |
def transcribe(audio, reference_text):
|
43 |
time.sleep(1)
|
44 |
text = p(audio)["text"]
|
@@ -46,95 +47,264 @@ def transcribe(audio, reference_text):
|
|
46 |
state = text
|
47 |
if state is not None:
|
48 |
if similar(reference_text, state) > 0.75:
|
49 |
-
score = "
|
50 |
elif similar(reference_text, state) > 0.50 and similar(reference_text, state) < 0.75:
|
51 |
score = "close"
|
52 |
else:
|
53 |
-
score = "wrong
|
54 |
return state, score
|
55 |
else :
|
56 |
print(" Null Object")
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
# Authentication function
|
59 |
def update_message(request: gr.Request):
|
60 |
return f"Welcome, {request.username}"
|
61 |
|
62 |
-
|
63 |
# Gradio apps
|
64 |
-
# get the list of the correct text to read
|
65 |
-
dropdown_choices = choices.keys()
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
|
|
|
|
|
|
|
|
70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
-
demo = gr.Blocks(theme=gr.themes.Soft())
|
73 |
|
74 |
with demo :
|
|
|
|
|
|
|
|
|
|
|
75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
gr.Markdown(
|
77 |
"""
|
78 |
-
|
79 |
-
Select a text from the list, read it aloud, and get the transcription along with the similarity score.
|
80 |
"""
|
81 |
)
|
82 |
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
close_text = gr.Textbox(label="Close Text")
|
88 |
-
wrong_text = gr.Textbox(label="Wrong Text")
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
|
|
98 |
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
-
|
102 |
-
|
103 |
-
transcribe_wrong_bn = gr.Button("Transcribe and Compare with Wrong", size="sm")
|
104 |
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
-
# Columns for outputs
|
109 |
-
with gr.Column():
|
110 |
-
trans_text = gr.Textbox(label="Transcription")
|
111 |
-
score = gr.Textbox(label="Score")
|
112 |
with gr.Row():
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
-
#
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
transcribe_correct_bn.click(fn=transcribe, inputs=[audio_record, correct_text], outputs=[trans_text, score])
|
123 |
-
transcribe_close_bn.click(fn=transcribe, inputs=[audio_record, close_text], outputs=[trans_text, score])
|
124 |
-
transcribe_wrong_bn.click(fn=transcribe, inputs=[audio_record, wrong_text], outputs=[trans_text, score])
|
125 |
-
|
126 |
-
# We can choose which components to flag
|
127 |
-
correct_flag_btn.click(lambda *args: correct_callback.flag(args), [correct_text, trans_text, score, audio_record], None, preprocess=False)
|
128 |
-
close_flag_btn.click(lambda *args: close_callback.flag(args), [close_text, trans_text, score, audio_record], None, preprocess=False)
|
129 |
-
wrong_flag_btn.click(lambda *args: wrong_callback.flag(args), [wrong_text, trans_text, score, audio_record], None, preprocess=False)
|
130 |
-
|
131 |
-
# Clear the recording
|
132 |
-
clear_btn.click(lambda: None, None, audio_record, queue=False)
|
133 |
|
134 |
-
# User authentication
|
135 |
-
m = gr.Markdown()
|
136 |
-
logout_button = gr.Button("Logout", link="/logout")
|
137 |
-
demo.load(update_message, None, m)
|
138 |
|
139 |
-
|
140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
# Read excel file and store it in a dictionary
|
13 |
def read_excel_data(file_path, sheet_name):
|
14 |
+
data_list = []
|
15 |
+
|
16 |
try:
|
17 |
# Read the Excel file
|
18 |
df = pd.read_excel(file_path, sheet_name=sheet_name)
|
19 |
# Iterate over the rows
|
20 |
for index, row in df.iterrows():
|
21 |
+
test = row['test']
|
22 |
+
correct = row['correct']
|
23 |
+
close = row['close']
|
24 |
+
wrong = row['wrong']
|
25 |
+
image = row["image"]
|
26 |
+
|
27 |
+
# Store close and wrong values as a tuple
|
28 |
+
data_list.append((test, correct, close, wrong, image))
|
29 |
+
return data_list
|
30 |
+
|
31 |
except Exception as e:
|
32 |
print(f"Error reading Excel file: {e}")
|
33 |
+
|
|
|
34 |
# List of sample texts to read
|
35 |
excel_file_path = "ASR_live_test.xlsx"
|
36 |
+
sheet_name= 'sample_test(threshold=75%)'
|
37 |
choices = read_excel_data(excel_file_path, sheet_name)
|
38 |
|
39 |
# Similarity function
|
40 |
def similar(a, b):
|
41 |
return SequenceMatcher(None, a, b).ratio()
|
42 |
|
|
|
43 |
def transcribe(audio, reference_text):
|
44 |
time.sleep(1)
|
45 |
text = p(audio)["text"]
|
|
|
47 |
state = text
|
48 |
if state is not None:
|
49 |
if similar(reference_text, state) > 0.75:
|
50 |
+
score = "correct"
|
51 |
elif similar(reference_text, state) > 0.50 and similar(reference_text, state) < 0.75:
|
52 |
score = "close"
|
53 |
else:
|
54 |
+
score = "wrong"
|
55 |
return state, score
|
56 |
else :
|
57 |
print(" Null Object")
|
58 |
|
59 |
+
# Function to retrieve the list of unique categories
|
60 |
+
def get_unique_tests(data_list):
|
61 |
+
tests=[]
|
62 |
+
tests = [test for test, _, _, _, _ in data_list if test not in tests]
|
63 |
+
return tests
|
64 |
+
|
65 |
+
# Function to retrieve close, wrong and image values for a given correct value
|
66 |
+
def get_values_image_for_test(tests, test):
|
67 |
+
for t, correct, close, wrong, image in tests:
|
68 |
+
if t == test:
|
69 |
+
return correct, close, wrong, image
|
70 |
+
|
71 |
+
# Counting completed tests
|
72 |
+
def completed_tests(test):
|
73 |
+
global completed_tests_list
|
74 |
+
if completed_tests_list is None:
|
75 |
+
completed_tests_list = []
|
76 |
+
|
77 |
+
if test and test not in completed_tests_list :
|
78 |
+
completed_tests_list.append(test)
|
79 |
+
|
80 |
+
# elif test and test in completed_tests_list:
|
81 |
+
# gr.Warning("Test alreday done! Please select another test.")
|
82 |
+
|
83 |
+
total_completed_tests = len(completed_tests_list)
|
84 |
+
return total_completed_tests, completed_tests_list
|
85 |
+
|
86 |
+
# Tracking user progress
|
87 |
+
def test_progress(test):
|
88 |
+
global completed_tests_list
|
89 |
+
|
90 |
+
# Get total completed tests
|
91 |
+
total_completed_tests, completed_tests_list = completed_tests(test)
|
92 |
+
completed_tests_text = "\n".join(completed_tests_list)
|
93 |
+
|
94 |
+
# Calculate how many tests are remaining
|
95 |
+
total_remaining_tests = len(choices) - total_completed_tests
|
96 |
+
|
97 |
+
if total_remaining_tests == 0:
|
98 |
+
completed_tests_list.clear()
|
99 |
+
progress_text = f"Congratulations! You have completed all tests"
|
100 |
+
else:
|
101 |
+
progress_text = f"You have completed {total_completed_tests} tests. {total_remaining_tests} tests are remaining"
|
102 |
+
return progress_text, completed_tests_text
|
103 |
+
|
104 |
+
# Tests ditribtution over users
|
105 |
+
import random
|
106 |
+
|
107 |
+
# Global set to store all available tests
|
108 |
+
categories_and_tests = choices
|
109 |
+
remaining_tests = set(get_unique_tests(categories_and_tests))
|
110 |
+
|
111 |
+
def assign_tests(categories_and_tests, num_tests):
|
112 |
+
global remaining_tests
|
113 |
+
assigned_tests = []
|
114 |
+
tests = get_unique_tests(categories_and_tests)
|
115 |
+
|
116 |
+
# Shuffle tests
|
117 |
+
random.shuffle(tests)
|
118 |
+
|
119 |
+
# last remaining tests are assigned to the last user
|
120 |
+
if num_tests > len(remaining_tests):
|
121 |
+
selected_tests = remaining_tests
|
122 |
+
|
123 |
+
# Ensure we still have enough tests
|
124 |
+
if len(remaining_tests) == 0:
|
125 |
+
print("***** Tests Completed *****")
|
126 |
+
#return ["Tests Completed"]
|
127 |
+
|
128 |
+
# Select tests that are not already assigned
|
129 |
+
assigned_tests = [test for test in tests if test in remaining_tests][:num_tests]
|
130 |
+
|
131 |
+
# Remove assigned tests from the set of all available tests
|
132 |
+
remaining_tests -= set(assigned_tests)
|
133 |
+
|
134 |
+
# # Update assigned tests set
|
135 |
+
# if len(assigned_tests) != 0:
|
136 |
+
# assigned_tests.append(selected_tests)
|
137 |
+
|
138 |
+
return assigned_tests
|
139 |
+
|
140 |
# Authentication function
|
141 |
def update_message(request: gr.Request):
|
142 |
return f"Welcome, {request.username}"
|
143 |
|
|
|
144 |
# Gradio apps
|
|
|
|
|
145 |
|
146 |
+
# Get test categories
|
147 |
+
data_list = choices
|
148 |
+
image_path="all_imgs/"
|
149 |
+
completed_tests_list = []
|
150 |
+
|
151 |
+
# Flagging
|
152 |
+
callback = gr.CSVLogger()
|
153 |
|
154 |
+
# CSS
|
155 |
+
css = """
|
156 |
+
h1 {
|
157 |
+
text-align: center;
|
158 |
+
color: #5756BB;
|
159 |
+
display:block;
|
160 |
+
}
|
161 |
+
p {
|
162 |
+
text-align: left;
|
163 |
+
display:block;
|
164 |
+
}
|
165 |
+
p.thick {
|
166 |
+
font-weight: bold;
|
167 |
+
}
|
168 |
+
.drop_color {background-color: #e0eaff}
|
169 |
+
img {
|
170 |
+
height: auto;
|
171 |
+
width: auto;
|
172 |
+
margin-left: auto;
|
173 |
+
margin-right: auto;
|
174 |
+
display: block;
|
175 |
+
}
|
176 |
+
.row {
|
177 |
+
height: 90px;
|
178 |
+
width: auto;
|
179 |
+
}
|
180 |
+
progress_text {
|
181 |
+
text-align: center;
|
182 |
+
ont-weight: bold;
|
183 |
+
}
|
184 |
+
"""
|
185 |
+
js = """
|
186 |
+
function change_color(){
|
187 |
+
const test_text = document.getElementById("#test_color");
|
188 |
+
const selectedtest = dropdown.options[dropdown.selectedIndex];
|
189 |
+
selectedtest.style.color = "green";
|
190 |
+
}
|
191 |
+
"""
|
192 |
|
193 |
+
demo = gr.Blocks(theme=gr.themes.Soft(), css=css)
|
194 |
|
195 |
with demo :
|
196 |
+
# Add app title
|
197 |
+
gr.Markdown(
|
198 |
+
"""
|
199 |
+
# Noorani Qaida Test Interface"""
|
200 |
+
)
|
201 |
|
202 |
+
# User authentication
|
203 |
+
with gr.Row():
|
204 |
+
m = gr.Markdown()
|
205 |
+
logout_button = gr.Button("Logout", link="/logout", scale=0, variant="primary")
|
206 |
+
demo.load(update_message, None, m)
|
207 |
+
|
208 |
+
# Add app description
|
209 |
gr.Markdown(
|
210 |
"""
|
211 |
+
Select a category then a test from the list, read the text aloud, get the transcription and save it.
|
|
|
212 |
"""
|
213 |
)
|
214 |
|
215 |
+
# Function to get the corresponding values of correct, close and wrong text and image for each test
|
216 |
+
num_tests = 10
|
217 |
+
assigned_tests = assign_tests(data_list, num_tests)
|
218 |
+
print(assigned_tests)
|
|
|
|
|
219 |
|
220 |
+
# Assign value to each step
|
221 |
+
def get_test_text(test):
|
222 |
+
correct, close, wrong, image = get_values_image_for_test(data_list, test)
|
223 |
+
correct_text = gr.Textbox(label="Step 1", value=correct)
|
224 |
+
close_text = gr.Textbox(label="Step 2", value=close)
|
225 |
+
wrong_text = gr.Textbox(label="Step 3", value=wrong)
|
226 |
+
image = gr.Image(value=(image_path+str(image)+".jpg"))
|
227 |
+
return correct_text, close_text, wrong_text, image
|
228 |
|
229 |
+
def update_completed_test(test):
|
230 |
+
_, completed_tests = gr.TextArea(completed_tests(test))
|
231 |
+
return completed_tests
|
232 |
|
233 |
+
with gr.Row(elem_classes="row"):
|
234 |
+
with gr.Column():
|
235 |
+
image = gr.Image(label="Written Form", elem_id="img", container=False, show_label=True, show_download_button=False)
|
236 |
+
|
237 |
+
with gr.Row():
|
238 |
+
# First column
|
239 |
+
with gr.Column():
|
240 |
|
241 |
+
# User progress
|
242 |
+
progress_text = gr.Textbox(info=" Your progress will appear here ", interactive=False, container=False, elem_id="progress_text", elem_classes="drop_color")
|
|
|
243 |
|
244 |
+
# Test selection
|
245 |
+
tests_list = assigned_tests
|
246 |
+
test_dropdown = gr.Dropdown(tests_list, label="Tests", info="Select a test", scale=1, elem_id="test_color", elem_classes="drop_color")
|
247 |
+
textarea_completed = gr.TextArea(info=" Your completed tests will appear here ", interactive=False, rtl=True, container=True, show_label=False, elem_classes="drop_color")
|
248 |
+
test_dropdown.select(test_progress, test_dropdown, outputs=[progress_text, textarea_completed])
|
249 |
+
|
250 |
+
with gr.Column():
|
251 |
+
correct_text = gr.Textbox(label= "Step 1", info="Correct Text", interactive=False, rtl=True)
|
252 |
+
correct_audio_record = gr.Audio(sources="microphone" ,type="filepath", label="Record Audio", show_label=False)
|
253 |
+
correct_trans_text = gr.Textbox(info="Transcription", interactive=False, rtl=True, show_label=False)
|
254 |
+
correct_score = gr.Textbox(label="Score", visible= False)
|
255 |
+
correct_audio_record.stop_recording(fn=transcribe, inputs=[correct_audio_record, correct_text], outputs=[correct_trans_text, correct_score])
|
256 |
+
|
257 |
+
# Third column
|
258 |
+
with gr.Column():
|
259 |
+
close_text = gr.Textbox(label="Step 2", info="Close Text", interactive=False, rtl=True)
|
260 |
+
close_audio_record = gr.Audio(sources="microphone", type="filepath", label="Record Audio", show_label=False)
|
261 |
+
close_trans_text = gr.Textbox(info="Transcription", interactive=False, rtl=True, show_label=False)
|
262 |
+
close_score = gr.Textbox(label="Score", visible= False)
|
263 |
+
close_audio_record.stop_recording(fn=transcribe, inputs=[close_audio_record, close_text], outputs=[close_trans_text, close_score])
|
264 |
+
|
265 |
+
# Fourth column
|
266 |
+
with gr.Column():
|
267 |
+
wrong_text = gr.Textbox(label="Step 3", info="Wrong Text", interactive=False, rtl=True)
|
268 |
+
wrong_audio_record = gr.Audio(sources="microphone" ,type="filepath", label="Record Audio", show_label=False)
|
269 |
+
wrong_trans_text = gr.Textbox(info="Transcription", interactive=False, rtl=True, show_label=False)
|
270 |
+
wrong_score = gr.Textbox(label="Score", visible= False)
|
271 |
+
wrong_audio_record.stop_recording(fn=transcribe, inputs=[wrong_audio_record, wrong_text], outputs=[wrong_trans_text, wrong_score])
|
272 |
|
|
|
|
|
|
|
|
|
273 |
with gr.Row():
|
274 |
+
#user_name = gr.Request.username
|
275 |
+
def save_outputs(correct_text, correct_trans_text, correct_score, correct_audio_record,
|
276 |
+
close_text, close_trans_text, close_score, close_audio_record,
|
277 |
+
wrong_text, wrong_trans_text, wrong_score, wrong_audio_record):
|
278 |
+
if any(len(text)==0 for text in [correct_trans_text, close_trans_text, wrong_trans_text]):
|
279 |
+
return gr.Warning("Please complete the test before saving")
|
280 |
+
return (lambda *args: callback.flag(args, username="randa"))
|
281 |
+
|
282 |
+
flag_btn = gr.Button(value="Save this test", variant="primary", scale=2)
|
283 |
+
# Setup the components to flag
|
284 |
+
callback.setup([correct_text, correct_trans_text, correct_score, correct_audio_record,
|
285 |
+
close_text, close_trans_text, close_score, close_audio_record,
|
286 |
+
wrong_text, wrong_trans_text, wrong_score, wrong_audio_record], "flagged_data")
|
287 |
+
# We can choose which components to flag
|
288 |
+
flag_btn.click(save_outputs,
|
289 |
+
[correct_text, correct_trans_text, correct_score, correct_audio_record,
|
290 |
+
close_text, close_trans_text, close_score, close_audio_record,
|
291 |
+
wrong_text, wrong_trans_text, wrong_score, wrong_audio_record],
|
292 |
+
None, preprocess=False)
|
293 |
+
|
294 |
+
# Update test values according to the selected test
|
295 |
+
test_dropdown.input(get_test_text, test_dropdown, [correct_text, close_text, wrong_text, image])
|
296 |
+
|
297 |
|
298 |
+
# Clear the transcription after selecting a new test
|
299 |
+
test_dropdown.select(lambda: [None]*10, None,
|
300 |
+
outputs=[correct_text, close_text, wrong_text, correct_audio_record, close_audio_record, wrong_audio_record, correct_trans_text, close_trans_text, wrong_trans_text, image],
|
301 |
+
queue=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
|
|
|
|
|
|
|
|
|
303 |
|
304 |
+
#demo.launch(inbrowser=True)
|
305 |
+
demo.launch(auth=[("randa", "randa"), ("randa1", "randa1"),("randa2", "randa2"), ("randa3", "randa3"),
|
306 |
+
("karim1", "karim1"), ("karim2", "karim2"), ("karim3", "karim3"),
|
307 |
+
("yassir1", "yassir1"), ("yassir2", "yassir2"), ("yassir3", "yassir3"),
|
308 |
+
("mehdi", "mehdi")],
|
309 |
+
share=True, inbrowser=True)
|
310 |
+
|