ciaochris commited on
Commit
d5a7f13
·
verified ·
1 Parent(s): c3e5e66

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -15
app.py CHANGED
@@ -30,6 +30,7 @@ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(
30
  # Initialize Groq client
31
  try:
32
  client = Groq(api_key=os.getenv("GROQ_API_KEY"))
 
33
  except Exception as e:
34
  logging.error(f"Error initializing Groq client: {str(e)}")
35
  raise EnvironmentError("Please set the GROQ_API_KEY environment variable")
@@ -40,6 +41,7 @@ def transcribe_audio(audio):
40
  return ""
41
 
42
  audio_path = audio if isinstance(audio, str) else audio.name
 
43
 
44
  with open(audio_path, "rb") as audio_file:
45
  audio_data = audio_file.read()
@@ -50,6 +52,7 @@ def transcribe_audio(audio):
50
  response_format="verbose_json",
51
  )
52
 
 
53
  return transcription.text
54
  except Exception as e:
55
  logging.error(f"Error in transcription: {str(e)}")
@@ -131,8 +134,9 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
131
  - Finally, provide the answer starting with "Answer:".
132
  3. Real-World Application: A challenging real-world application of this concept, demonstrating its practical use.
133
  4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
134
- Format your entire response as a JSON object with keys: "lesson", "example", "real_world_problem", "quiz".
135
- Ensure that the content for each key is a single string, with line breaks where appropriate.
 
136
  """
137
  else:
138
  prompt = f"""
@@ -145,11 +149,13 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
145
  - Finally, provide the answer starting with "Answer:".
146
  3. Real-World Application: Describe a real-world problem that can be solved using the concepts from the lesson.
147
  4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
148
- Format your entire response as a JSON object with keys: "lesson", "example", "real_world_problem", "quiz".
149
- Ensure that the content for each key is a single string, with line breaks where appropriate.
 
150
  """
151
 
152
  try:
 
153
  completion = client.chat.completions.create(
154
  messages=[
155
  {
@@ -164,11 +170,59 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
164
  model="llama-3.3-70b-versatile",
165
  max_tokens=2000,
166
  )
167
- # Parse the JSON string into a dictionary before returning
168
- return json.loads(completion.choices[0].message.content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  except Exception as e:
170
  logging.error(f"Error generating tutor output: {str(e)}")
171
- return {"error": f"Failed to generate tutor output: {str(e)}"}
 
 
 
 
 
172
 
173
  def process_output(output: Dict[str, Any]) -> Tuple[str, str, str, str]:
174
  try:
@@ -179,7 +233,7 @@ def process_output(output: Dict[str, Any]) -> Tuple[str, str, str, str]:
179
  return lesson, example, real_world, quiz
180
  except Exception as e:
181
  logging.error(f"Error processing output: {str(e)}")
182
- return str(e), "", "", ""
183
 
184
  def transcribe_and_display(audio):
185
  if not audio:
@@ -196,12 +250,14 @@ def create_interface() -> gr.Blocks:
196
  subject = gr.Dropdown(
197
  ["Art History", "Computer Science", "Literature", "Math", "Music", "Science", "Social Science"],
198
  label="Subject",
199
- info="Choose the subject of your lesson"
 
200
  )
201
  difficulty = gr.Radio(
202
  ["Primary", "Secondary", "Higher Education"],
203
  label="Difficulty Level",
204
- info="Select your proficiency level"
 
205
  )
206
  student_input = gr.Textbox(
207
  placeholder="Type your topic or question here...",
@@ -244,33 +300,47 @@ def create_interface() -> gr.Blocks:
244
 
245
  def process_input(subject, difficulty, text_input, audio_input, transcribed_text_state):
246
  try:
247
- if audio_input:
 
248
  student_input = transcribed_text_state
249
  transcribed_output_value = transcribed_text_state
250
- else:
 
251
  student_input = text_input
252
  transcribed_output_value = ""
 
 
 
 
253
 
254
- logging.info(f"Processing input: subject={subject}, difficulty={difficulty}, student_input={student_input}")
255
 
 
256
  tutor_output = generate_tutor_output(subject.lower(), difficulty, student_input)
 
 
257
  lesson, example, real_world, quiz = process_output(tutor_output)
 
 
258
  return transcribed_output_value, lesson, example, real_world, quiz
259
  except Exception as e:
260
  logging.error(f"Error in process_input: {str(e)}")
261
- return str(e), "Error generating lesson", "Error generating example", "Error generating real-world problem", "Error generating quiz"
262
 
263
  def clear_outputs():
264
- return "" * 5 # Empty strings for all outputs
265
 
 
266
  audio_input.upload(transcribe_and_display, audio_input, [transcription_output, transcribed_text_state])
267
 
 
268
  submit_button.click(
269
  fn=process_input,
270
  inputs=[subject, difficulty, student_input, audio_input, transcribed_text_state],
271
  outputs=[transcription_output, lesson_output, example_output, real_world_output, quiz_output]
272
  )
273
 
 
274
  clear_button.click(
275
  fn=clear_outputs,
276
  inputs=[],
 
30
  # Initialize Groq client
31
  try:
32
  client = Groq(api_key=os.getenv("GROQ_API_KEY"))
33
+ logging.info("Groq client initialized successfully")
34
  except Exception as e:
35
  logging.error(f"Error initializing Groq client: {str(e)}")
36
  raise EnvironmentError("Please set the GROQ_API_KEY environment variable")
 
41
  return ""
42
 
43
  audio_path = audio if isinstance(audio, str) else audio.name
44
+ logging.info(f"Transcribing audio from {audio_path}")
45
 
46
  with open(audio_path, "rb") as audio_file:
47
  audio_data = audio_file.read()
 
52
  response_format="verbose_json",
53
  )
54
 
55
+ logging.info(f"Transcription successful: {transcription.text[:50]}...")
56
  return transcription.text
57
  except Exception as e:
58
  logging.error(f"Error in transcription: {str(e)}")
 
134
  - Finally, provide the answer starting with "Answer:".
135
  3. Real-World Application: A challenging real-world application of this concept, demonstrating its practical use.
136
  4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
137
+ Format your entire response as a valid JSON object with ONLY these keys: "lesson", "example", "real_world_problem", "quiz".
138
+ Each value should be a string. DO NOT include any text outside of the JSON structure.
139
+ Your response should parse correctly when passed to json.loads().
140
  """
141
  else:
142
  prompt = f"""
 
149
  - Finally, provide the answer starting with "Answer:".
150
  3. Real-World Application: Describe a real-world problem that can be solved using the concepts from the lesson.
151
  4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
152
+ Format your entire response as a valid JSON object with ONLY these keys: "lesson", "example", "real_world_problem", "quiz".
153
+ Each value should be a string. DO NOT include any text outside of the JSON structure.
154
+ Your response should parse correctly when passed to json.loads().
155
  """
156
 
157
  try:
158
+ logging.info(f"Sending request to Groq API for subject: {subject}, difficulty: {difficulty}")
159
  completion = client.chat.completions.create(
160
  messages=[
161
  {
 
170
  model="llama-3.3-70b-versatile",
171
  max_tokens=2000,
172
  )
173
+
174
+ logging.info("Successfully received response from Groq API")
175
+
176
+ try:
177
+ # Try to parse the JSON response
178
+ raw_content = completion.choices[0].message.content
179
+ logging.info(f"Raw API response preview: {raw_content[:100]}...")
180
+ result = json.loads(raw_content)
181
+ logging.info("Successfully parsed JSON response")
182
+ return result
183
+ except json.JSONDecodeError as json_err:
184
+ # If JSON parsing fails, log the error and return the raw content in a structured format
185
+ logging.error(f"JSON parsing error: {str(json_err)}")
186
+ raw_content = completion.choices[0].message.content
187
+
188
+ # Try to extract content using basic string parsing if JSON fails
189
+ lesson_content = "The model didn't return properly formatted JSON. Here's the response:"
190
+ example_content = "Error processing example."
191
+ real_world_content = "Error processing real-world problem."
192
+ quiz_content = "Error processing quiz."
193
+
194
+ # Try to extract sections using markers
195
+ if "Lesson:" in raw_content:
196
+ lesson_parts = raw_content.split("Lesson:")[1].split("Example:")[0] if "Example:" in raw_content else raw_content.split("Lesson:")[1]
197
+ lesson_content = "Lesson: " + lesson_parts.strip()
198
+
199
+ if "Example:" in raw_content:
200
+ example_parts = raw_content.split("Example:")[1].split("Real-World Application:")[0] if "Real-World Application:" in raw_content else raw_content.split("Example:")[1]
201
+ example_content = "Example: " + example_parts.strip()
202
+
203
+ if "Real-World Application:" in raw_content:
204
+ real_world_parts = raw_content.split("Real-World Application:")[1].split("Quiz:")[0] if "Quiz:" in raw_content else raw_content.split("Real-World Application:")[1]
205
+ real_world_content = "Real-World Application: " + real_world_parts.strip()
206
+
207
+ if "Quiz:" in raw_content:
208
+ quiz_parts = raw_content.split("Quiz:")[1]
209
+ quiz_content = "Quiz: " + quiz_parts.strip()
210
+
211
+ # Return a formatted response that won't cause downstream errors
212
+ return {
213
+ "lesson": lesson_content,
214
+ "example": example_content,
215
+ "real_world_problem": real_world_content,
216
+ "quiz": quiz_content
217
+ }
218
  except Exception as e:
219
  logging.error(f"Error generating tutor output: {str(e)}")
220
+ return {
221
+ "lesson": f"Failed to generate lesson: {str(e)}",
222
+ "example": "Error: Could not generate example.",
223
+ "real_world_problem": "Error: Could not generate real-world problem.",
224
+ "quiz": "Error: Could not generate quiz."
225
+ }
226
 
227
  def process_output(output: Dict[str, Any]) -> Tuple[str, str, str, str]:
228
  try:
 
233
  return lesson, example, real_world, quiz
234
  except Exception as e:
235
  logging.error(f"Error processing output: {str(e)}")
236
+ return f"Error: {str(e)}", "Error processing example", "Error processing real-world problem", "Error processing quiz"
237
 
238
  def transcribe_and_display(audio):
239
  if not audio:
 
250
  subject = gr.Dropdown(
251
  ["Art History", "Computer Science", "Literature", "Math", "Music", "Science", "Social Science"],
252
  label="Subject",
253
+ info="Choose the subject of your lesson",
254
+ value="Math" # Set default value
255
  )
256
  difficulty = gr.Radio(
257
  ["Primary", "Secondary", "Higher Education"],
258
  label="Difficulty Level",
259
+ info="Select your proficiency level",
260
+ value="Secondary" # Set default value
261
  )
262
  student_input = gr.Textbox(
263
  placeholder="Type your topic or question here...",
 
300
 
301
  def process_input(subject, difficulty, text_input, audio_input, transcribed_text_state):
302
  try:
303
+ # Determine which input to use
304
+ if audio_input and transcribed_text_state:
305
  student_input = transcribed_text_state
306
  transcribed_output_value = transcribed_text_state
307
+ logging.info(f"Using transcribed audio input: {student_input[:50]}...")
308
+ elif text_input:
309
  student_input = text_input
310
  transcribed_output_value = ""
311
+ logging.info(f"Using text input: {student_input[:50]}...")
312
+ else:
313
+ logging.warning("No input provided")
314
+ return "No input provided", "Please provide a question either by typing or speaking.", "", "", ""
315
 
316
+ logging.info(f"Processing input: subject={subject}, difficulty={difficulty}")
317
 
318
+ # Generate tutor output
319
  tutor_output = generate_tutor_output(subject.lower(), difficulty, student_input)
320
+
321
+ # Process the output
322
  lesson, example, real_world, quiz = process_output(tutor_output)
323
+ logging.info("Successfully processed tutor output")
324
+
325
  return transcribed_output_value, lesson, example, real_world, quiz
326
  except Exception as e:
327
  logging.error(f"Error in process_input: {str(e)}")
328
+ return str(e), f"Error generating lesson: {str(e)}", "Error generating example", "Error generating real-world problem", "Error generating quiz"
329
 
330
  def clear_outputs():
331
+ return ["", "", "", "", ""] # Five empty strings for all outputs
332
 
333
+ # Connect the audio input to the transcription function
334
  audio_input.upload(transcribe_and_display, audio_input, [transcription_output, transcribed_text_state])
335
 
336
+ # Connect the submit button
337
  submit_button.click(
338
  fn=process_input,
339
  inputs=[subject, difficulty, student_input, audio_input, transcribed_text_state],
340
  outputs=[transcription_output, lesson_output, example_output, real_world_output, quiz_output]
341
  )
342
 
343
+ # Connect the clear button
344
  clear_button.click(
345
  fn=clear_outputs,
346
  inputs=[],