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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -138
app.py CHANGED
@@ -30,7 +30,6 @@ 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
- 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,18 +40,17 @@ def transcribe_audio(audio):
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()
48
 
 
49
  transcription = client.audio.transcriptions.create(
50
  file=(os.path.basename(audio_path), audio_data),
51
  model="distil-whisper-large-v3-en",
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)}")
@@ -75,41 +73,7 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
75
  "dna replication": "the process of DNA replication and its importance in cell division",
76
  "climate change": "the causes and effects of climate change, including global warming and its impact on ecosystems"
77
  },
78
- "art history": {
79
- "renaissance art": "The art and artists of the Renaissance period, including Leonardo da Vinci, Michel angelo, and Raffaello.",
80
- "ancient egyptian art": "Art forms, techniques, and cultural significance of ancient Egyptian art.",
81
- "impressionism": "The impressionist movement in art, key artists, and their works.",
82
- "cubism": "The cubist movement, pioneered by Pablo Picasso and Georges Braque.",
83
- "modern art": "Art from the late 19th century to the present, including abstract expressionism, pop art, etc."
84
- },
85
- "computer science": {
86
- "algorithms": "Study of algorithms, their design, analysis, and implementation.",
87
- "data structures": "Different data structures and their applications in computer science.",
88
- "programming languages": "Overview of various programming languages, their features, and uses.",
89
- "artificial intelligence": "Basics of AI, machine learning, neural networks, etc.",
90
- "cybersecurity": "Principles of cybersecurity, threats, and protection mechanisms."
91
- },
92
- "literature": {
93
- "shakespeare": "Works of William Shakespeare, his plays and sonnets.",
94
- "classic novels": "Notable novels from the 18th, 19th, and early 20th centuries.",
95
- "modern fiction": "Contemporary novels and their authors.",
96
- "poetry": "Different forms of poetry and notable poets.",
97
- "drama": "Theater and dramatic literature."
98
- },
99
- "music": {
100
- "classical music": "Music from the medieval period to the present, focusing on classical compositions.",
101
- "pop music": "Popular music genres and artists.",
102
- "jazz": "History and styles of jazz music.",
103
- "rock and roll": "Evolution of rock music and its influential bands.",
104
- "music theory": "Fundamentals of music theory, notation, and composition."
105
- },
106
- "social science": {
107
- "economics": "Principles of micro and macroeconomics, economic systems, and policies.",
108
- "sociology": "Study of society, social behavior, and cultural norms.",
109
- "psychology": "Human behavior, mental processes, and psychological disorders.",
110
- "anthropology": "Study of human cultures, evolution, and societies.",
111
- "geography": "Earth's physical and human features, maps, and spatial analysis."
112
- }
113
  }
114
 
115
  # Check if it's a specific topic and create an enhanced prompt
@@ -134,9 +98,8 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
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,13 +112,11 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
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,59 +131,11 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
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,13 +146,7 @@ def process_output(output: Dict[str, Any]) -> Tuple[str, str, str, str]:
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:
240
- return "", ""
241
- transcription = transcribe_audio(audio)
242
- return transcription, transcription
243
 
244
  def create_interface() -> gr.Blocks:
245
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
@@ -250,14 +157,12 @@ def create_interface() -> gr.Blocks:
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...",
@@ -265,13 +170,12 @@ def create_interface() -> gr.Blocks:
265
  info="Enter the topic you want to explore"
266
  )
267
  audio_input = gr.Audio(type="filepath", label="Speak Your Question")
268
- transcribed_text_state = gr.State("")
269
- transcription_output = gr.Textbox(label="Transcribed Audio (if provided)")
270
  with gr.Row():
271
  submit_button = gr.Button("📚 Teach Me", variant="primary")
272
  clear_button = gr.Button("🧹 Clear", variant="secondary")
273
 
274
  with gr.Column(scale=3):
 
275
  lesson_output = gr.HTML(label="Lesson")
276
  example_output = gr.HTML(label="Example")
277
  real_world_output = gr.HTML(label="Real-World Application")
@@ -298,49 +202,33 @@ def create_interface() -> gr.Blocks:
298
  Note: Make sure your browser has permission to access your microphone. If you encounter any issues, try using a different browser or check your device's audio settings.
299
  """)
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=[],
@@ -348,7 +236,7 @@ def create_interface() -> gr.Blocks:
348
  )
349
 
350
  return demo
351
-
352
  if __name__ == "__main__":
353
  demo = create_interface()
354
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
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
  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()
46
 
47
+ # Transcribe the audio using Distil-Whisper
48
  transcription = client.audio.transcriptions.create(
49
  file=(os.path.basename(audio_path), audio_data),
50
  model="distil-whisper-large-v3-en",
51
  response_format="verbose_json",
52
  )
53
 
 
54
  return transcription.text
55
  except Exception as e:
56
  logging.error(f"Error in transcription: {str(e)}")
 
73
  "dna replication": "the process of DNA replication and its importance in cell division",
74
  "climate change": "the causes and effects of climate change, including global warming and its impact on ecosystems"
75
  },
76
+ # Add more subjects and topics as needed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
  # Check if it's a specific topic and create an enhanced prompt
 
98
  - Finally, provide the answer starting with "Answer:".
99
  3. Real-World Application: A challenging real-world application of this concept, demonstrating its practical use.
100
  4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
101
+ Format your entire response as a JSON object with keys: "lesson", "example", "real_world_problem", "quiz".
102
+ Ensure that the content for each key is a single string, with line breaks where appropriate.
 
103
  """
104
  else:
105
  prompt = f"""
 
112
  - Finally, provide the answer starting with "Answer:".
113
  3. Real-World Application: Describe a real-world problem that can be solved using the concepts from the lesson.
114
  4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
115
+ Format your entire response as a JSON object with keys: "lesson", "example", "real_world_problem", "quiz".
116
+ Ensure that the content for each key is a single string, with line breaks where appropriate.
 
117
  """
118
 
119
  try:
 
120
  completion = client.chat.completions.create(
121
  messages=[
122
  {
 
131
  model="llama-3.3-70b-versatile",
132
  max_tokens=2000,
133
  )
134
+ # Parse the JSON string into a dictionary before returning
135
+ return json.loads(completion.choices[0].message.content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  except Exception as e:
137
  logging.error(f"Error generating tutor output: {str(e)}")
138
+ return {"error": f"Failed to generate tutor output: {str(e)}"}
 
 
 
 
 
139
 
140
  def process_output(output: Dict[str, Any]) -> Tuple[str, str, str, str]:
141
  try:
 
146
  return lesson, example, real_world, quiz
147
  except Exception as e:
148
  logging.error(f"Error processing output: {str(e)}")
149
+ return str(e), "", "", ""
 
 
 
 
 
 
150
 
151
  def create_interface() -> gr.Blocks:
152
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
 
157
  subject = gr.Dropdown(
158
  ["Art History", "Computer Science", "Literature", "Math", "Music", "Science", "Social Science"],
159
  label="Subject",
160
+ info="Choose the subject of your lesson"
 
161
  )
162
  difficulty = gr.Radio(
163
  ["Primary", "Secondary", "Higher Education"],
164
  label="Difficulty Level",
165
+ info="Select your proficiency level"
 
166
  )
167
  student_input = gr.Textbox(
168
  placeholder="Type your topic or question here...",
 
170
  info="Enter the topic you want to explore"
171
  )
172
  audio_input = gr.Audio(type="filepath", label="Speak Your Question")
 
 
173
  with gr.Row():
174
  submit_button = gr.Button("📚 Teach Me", variant="primary")
175
  clear_button = gr.Button("🧹 Clear", variant="secondary")
176
 
177
  with gr.Column(scale=3):
178
+ transcription_output = gr.Textbox(label="Transcribed Audio (if provided)")
179
  lesson_output = gr.HTML(label="Lesson")
180
  example_output = gr.HTML(label="Example")
181
  real_world_output = gr.HTML(label="Real-World Application")
 
202
  Note: Make sure your browser has permission to access your microphone. If you encounter any issues, try using a different browser or check your device's audio settings.
203
  """)
204
 
205
+ def process_input(subject, difficulty, text_input, audio_input):
206
  try:
207
+ if audio_input:
208
+ transcribed_text = transcribe_audio(audio_input)
209
+ student_input = transcribed_text
 
 
 
 
 
 
210
  else:
211
+ student_input = text_input
212
+ transcribed_text = ""
 
 
213
 
214
+ logging.info(f"Processing input: subject={subject}, difficulty={difficulty}, student_input={student_input}")
 
215
 
216
+ tutor_output = generate_tutor_output(subject, difficulty, student_input)
217
  lesson, example, real_world, quiz = process_output(tutor_output)
218
+ return transcribed_text, lesson, example, real_world, quiz
 
 
219
  except Exception as e:
220
  logging.error(f"Error in process_input: {str(e)}")
221
+ return str(e), "Error generating lesson", "Error generating example", "Error generating real-world problem", "Error generating quiz"
222
 
223
  def clear_outputs():
224
+ return [""] * 5 # Clear all five output fields
225
 
 
 
 
 
226
  submit_button.click(
227
  fn=process_input,
228
+ inputs=[subject, difficulty, student_input, audio_input],
229
  outputs=[transcription_output, lesson_output, example_output, real_world_output, quiz_output]
230
  )
231
 
 
232
  clear_button.click(
233
  fn=clear_outputs,
234
  inputs=[],
 
236
  )
237
 
238
  return demo
239
+
240
  if __name__ == "__main__":
241
  demo = create_interface()
242
  demo.launch(server_name="0.0.0.0", server_port=7860)