pykara commited on
Commit
fc01712
·
verified ·
1 Parent(s): 43c3b55

Update generateQuestion.py

Browse files
Files changed (1) hide show
  1. generateQuestion.py +68 -143
generateQuestion.py CHANGED
@@ -2,29 +2,17 @@
2
  from flask import Flask, Blueprint, jsonify, send_file, abort, make_response, request, current_app
3
 
4
  from flask_cors import CORS
5
- # from moviepy.editor import VideoFileClip
6
- # from google.cloud import speech
7
  import os
8
  print(f"GOOGLE_APPLICATION_CREDENTIALS: {os.getenv('GOOGLE_APPLICATION_CREDENTIALS')}")
9
  import io
10
  import uuid
11
  import requests
12
- # from pydub import AudioSegment
13
- # import ffmpeg
14
  import re
15
 
16
-
17
-
18
-
19
  questions_bp = Blueprint("questions", __name__)
20
 
21
-
22
-
23
-
24
-
25
  app = Flask(__name__)
26
  CORS(app)
27
- # CORS(app, resources={r"/*": {"origins": "*"}})
28
 
29
  @app.route('/')
30
  def home():
@@ -46,22 +34,23 @@ def _cohere_headers():
46
  "Content-Type": "application/json",
47
  }
48
 
49
- # API configuration for AI-based question generation
50
- # COHERE_API_KEY = 'WjnDKknACe0zxHvczdo7q4vwF4WAXn2429hcPHIB'
51
- COHERE_API_URL = 'https://api.cohere.ai/v1/generate'
52
-
53
- # Google Cloud Speech-to-Text Configuration
54
- # speech_client = speech.SpeechClient()
55
-
56
-
57
-
58
-
59
-
60
-
61
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  def validate_topic(topic):
64
-
65
  validation_prompt = f"""
66
  ou are a highly knowledgeable AI grammar expert. Your task is to evaluate whether the given topic relates to **English grammar** or not.
67
 
@@ -82,61 +71,44 @@ def validate_topic(topic):
82
  No extra text or explanation.
83
  """
84
 
85
-
86
-
87
-
88
-
89
-
90
- # headers = {
91
- # 'Authorization': f'Bearer {COHERE_API_KEY}',
92
- # 'Content-Type': 'application/json'
93
- # }
94
  headers = _cohere_headers()
95
  if not headers:
96
  return "Error: COHERE_API_KEY not set"
97
 
 
98
  payload = {
99
  'model': 'command-r-08-2024',
100
- 'prompt': validation_prompt,
101
- 'max_tokens': 5 # Minimal token usage for classification
 
 
102
  }
103
 
104
  try:
105
  response = requests.post(COHERE_API_URL, json=payload, headers=headers)
106
- validation_result = response.json().get('generations', [{}])[0].get('text', '').strip()
107
-
108
- # Ensure the response is strictly "Grammar" or "Not Grammar"
109
- if validation_result not in ["Grammar", "Not Grammar"]:
110
- return "Not Grammar" # Fallback to avoid incorrect responses
111
 
 
 
112
  return validation_result
113
 
114
  except Exception as e:
115
  return f"Error: {str(e)}"
116
 
117
  @questions_bp.post('/generate-questions')
118
- # @app.route('/generate-questions', methods=['POST'])
119
  def generate_questions_test():
120
  try:
121
  data = request.get_json()
122
- topic = data.get('topic', '').strip() # Default to "grammar" if no topic is provided
123
- # levels = data.get('levels', ['basic', 'medium', 'hard'])
124
-
125
-
126
  validation_result = validate_topic(topic)
127
 
128
  if validation_result != "Grammar":
129
  return jsonify({"message": "Please enter a valid **grammar topic**, not a general word or unrelated question."}), 400
130
 
131
-
132
  difficulty = data.get('difficulty', 'basic')
133
-
134
-
135
- # Debugging output
136
  print(f"Generating {difficulty} questions for topic: {topic}")
137
 
138
-
139
-
140
  if difficulty == 'basic':
141
  prompt = f"""
142
  Generate five **completely new and unique** very basic-level fill-in-the-blank grammar questions **every time** on the topic '{topic}'.
@@ -151,7 +123,6 @@ def generate_questions_test():
151
  - Each question must include the correct answer in parentheses at the end.
152
  - Do not include any explanations or instructions—only the five questions.
153
  """
154
-
155
  elif difficulty == 'intermediate':
156
  prompt = f"""
157
  Generate five **completely new and unique** intermediate-level fill-in-the-blank grammar questions **every time** on the topic '{topic}'.
@@ -166,7 +137,6 @@ def generate_questions_test():
166
  - Each question must include the correct answer in parentheses at the end.
167
  - Do not include any explanations or instructions—only the five questions.
168
  """
169
-
170
  elif difficulty == 'expert':
171
  prompt = f"""
172
  Generate five **completely new and unique** advanced-level (C1) fill-in-the-blank grammar questions **every time** on the topic '{topic}'.
@@ -181,56 +151,47 @@ def generate_questions_test():
181
  - Each question must include the correct answer in parentheses at the end.
182
  - Do not include any explanations or instructions—only the five questions.
183
  """
184
-
185
-
186
-
187
  else:
188
  return jsonify({"error": "Invalid difficulty level"}), 400
189
 
190
- # headers = {
191
- # 'Authorization': f'Bearer {COHERE_API_KEY}',
192
- # 'Content-Type': 'application/json'
193
- # }
194
  headers = _cohere_headers()
195
  if not headers:
196
  return jsonify({"error": "COHERE_API_KEY not set on the server"}), 500
197
 
 
198
  payload = {
199
- 'model': 'command-r-08-2024', # Ensure you're using the right model
200
- 'prompt': prompt,
201
- 'max_tokens': 1000 # Increase the token limit if needed
 
 
202
  }
203
 
204
- # Make the API request
205
  response = requests.post(COHERE_API_URL, json=payload, headers=headers)
206
-
207
- # Log the full response for debugging
208
  print("Response status code:", response.status_code)
209
  print("Response content:", response.text)
210
 
211
  if response.status_code == 200:
212
- return jsonify(response.json()) # Return the response from Cohere API
 
 
 
213
  else:
214
  return jsonify({"error": "Failed to fetch questions", "details": response.text}), 500
215
  except Exception as e:
216
  return jsonify({"error": str(e)}), 500
217
 
218
- # Endpoint to validate answers
219
  @questions_bp.post('/validate-answer')
220
- # @app.route('/validate-answer', methods=['POST'])
221
  def validate_answer():
222
  try:
223
- # Get the data from the request
224
  data = request.get_json()
225
- topic = data.get('topic', '') # Get the topic
226
  question = data.get('question', '')
227
  user_answer = data.get('user_answer', '')
228
 
229
- # Validate if the required fields are present
230
  if not question or not user_answer or not topic:
231
- return jsonify({'error': 'Topic, question, and user answer are required'}), 400
232
 
233
- # Construct the prompt for Cohere API
234
  prompt = f"""
235
  You are a highly knowledgeable grammar assistant. Validate whether the user's answer to the following question is correct or not based on {topic}. If the answer is incorrect, provide a helpful hint.
236
 
@@ -241,48 +202,37 @@ def validate_answer():
241
  Is the answer correct? If not, please explain why and give a hint.
242
  """
243
 
244
- # Headers and payload for the Cohere API request
245
- # headers = {
246
- # 'Authorization': f'Bearer {COHERE_API_KEY}',
247
- # 'Content-Type': 'application/json'
248
- # }
249
-
250
  headers = _cohere_headers()
251
  if not headers:
252
  return jsonify({"error": "COHERE_API_KEY not set on the server"}), 500
253
 
 
254
  payload = {
255
- 'model': 'command-r-08-2024', # Use your model name here
256
- 'prompt': prompt,
 
 
257
  'max_tokens': 100,
258
  'temperature': 0.7
259
  }
260
 
261
- # Make the API call to Cohere
262
  response = requests.post(COHERE_API_URL, headers=headers, json=payload)
263
-
264
- # Debugging: Log response status and body
265
  print(f"Status Code: {response.status_code}")
266
  print(f"Response Body: {response.text}")
267
 
268
- # Check if the request was successful
269
  if response.status_code == 200:
270
- data = response.json()
271
- return jsonify(data)
 
272
  else:
273
  return jsonify({'error': 'Failed to fetch data from Cohere API'}), 500
274
 
275
  except Exception as e:
276
  return jsonify({'error': str(e)}), 500
277
 
278
-
279
-
280
- # // for validating Multiple answer:
281
-
282
  # Function to validate an individual answer using Cohere API
283
  def validate_answer_with_ai(topic, question, user_answer):
284
  try:
285
- # Construct the prompt for Cohere API
286
  prompt = f"""
287
  You are a highly knowledgeable grammar assistant. Validate whether the user's answer to the following question is correct or not based on {topic}. If the answer is incorrect, provide a helpful hint.
288
 
@@ -293,47 +243,35 @@ def validate_answer_with_ai(topic, question, user_answer):
293
  Is the answer correct? If not, please explain why and give a hint.
294
  """
295
 
296
- # Headers for the API request
297
- # headers = {
298
- # 'Authorization': f'Bearer {COHERE_API_KEY}',
299
- # 'Content-Type': 'application/json'
300
- # }
301
-
302
  headers = _cohere_headers()
303
  if not headers:
304
  return "Error: COHERE_API_KEY not set"
305
 
306
- # Construct the payload for Cohere API request
307
  payload = {
308
- 'model': 'command-r-08-2024', # You can use a different model depending on your needs
309
- 'prompt': prompt,
 
 
310
  'max_tokens': 200,
311
- 'temperature': 0.7,
312
- 'stop_sequences': ['\n']
313
  }
314
 
315
- # Make the POST request to the Cohere API
316
- response = requests.post('https://api.cohere.ai/v1/generate', headers=headers, json=payload)
317
 
318
  if response.status_code == 200:
319
- result = response.json()
320
- # Extract and return the relevant part of the response
321
- validation_response = result['generations'][0]['text'].strip()
322
- return validation_response
323
  else:
324
  return f"Error: {response.status_code} - {response.text}"
325
 
326
  except Exception as e:
327
  return f"An error occurred: {str(e)}"
328
 
329
-
330
-
331
  @questions_bp.post('/validate-all-answers')
332
- # Endpoint to validate multiple answers at once
333
- # @app.route('/validate-all-answers', methods=['POST'])
334
  def validate_all_answers():
335
  try:
336
- # Get the list of questions and answers from the request body
337
  data = request.get_json()
338
  questions = data.get('questions', [])
339
 
@@ -342,7 +280,6 @@ def validate_all_answers():
342
 
343
  validation_results = []
344
 
345
- # Iterate over the list of questions and validate each answer
346
  for item in questions:
347
  topic = item.get('topic', '')
348
  question = item.get('question', '')
@@ -355,20 +292,19 @@ def validate_all_answers():
355
  })
356
  continue
357
 
358
- # Validate the answer with the Cohere API
359
  validation_response = validate_answer_with_ai(topic, question, user_answer)
360
 
361
- # If the answer is incorrect, generate a hint
362
  hint = None
363
- if "incorrect" in validation_response.lower() or "not correct" in validation_response.lower():
364
- # Generate the hint for the incorrect answer
 
365
  hint = generate_hint(topic, question, user_answer)
366
 
367
  validation_results.append({
368
  'question': question,
369
  'user_answer': user_answer,
370
  'validation_response': validation_response,
371
- 'hint': hint # Add hint to the result
372
  })
373
 
374
  return jsonify({'results': validation_results})
@@ -376,11 +312,8 @@ def validate_all_answers():
376
  except Exception as e:
377
  return jsonify({'error': str(e)}), 500
378
 
379
-
380
-
381
  def generate_hint(topic, question, user_answer):
382
  try:
383
- # Construct the prompt for Cohere API to generate a hint for incorrect answers
384
  prompt = f"""
385
  You are a highly skilled grammar assistant. Your task is to generate a helpful hint for the user to improve their answer based on the following question.
386
 
@@ -397,39 +330,31 @@ def generate_hint(topic, question, user_answer):
397
  Please make sure the hint is **clear** and **helpful** for the user, **without revealing the correct answer**.
398
  """
399
 
400
- # headers = {
401
- # 'Authorization': f'Bearer {COHERE_API_KEY}',
402
- # 'Content-Type': 'application/json'
403
- # }
404
-
405
  headers = _cohere_headers()
406
  if not headers:
407
  return "Error: COHERE_API_KEY not set"
408
 
 
409
  payload = {
410
- 'model': 'command-r-08-2024', # Replace with the model you're using
411
- 'prompt': prompt,
412
- 'max_tokens': 250, # Adjust token size as needed
413
- 'temperature': 0.7, # Use temperature to control creativity
 
 
414
  }
415
 
416
- # Make the POST request to Cohere API
417
  response = requests.post(COHERE_API_URL, headers=headers, json=payload)
418
 
419
  if response.status_code == 200:
420
- result = response.json()
421
- # Extract and return the relevant hint from the response
422
- hint = result['generations'][0]['text'].strip()
423
- return hint
424
  else:
425
  return f"Error: {response.status_code} - {response.text}"
426
 
427
  except Exception as e:
428
  return f"An error occurred: {str(e)}"
429
 
430
-
431
  if __name__ == '__main__':
432
- # app.run(debug=True)
433
- app.register_blueprint(questions_bp, url_prefix='') # expose /explain-grammar locally
434
  app.run(host='0.0.0.0', port=5012, debug=True)
435
-
 
2
  from flask import Flask, Blueprint, jsonify, send_file, abort, make_response, request, current_app
3
 
4
  from flask_cors import CORS
 
 
5
  import os
6
  print(f"GOOGLE_APPLICATION_CREDENTIALS: {os.getenv('GOOGLE_APPLICATION_CREDENTIALS')}")
7
  import io
8
  import uuid
9
  import requests
 
 
10
  import re
11
 
 
 
 
12
  questions_bp = Blueprint("questions", __name__)
13
 
 
 
 
 
14
  app = Flask(__name__)
15
  CORS(app)
 
16
 
17
  @app.route('/')
18
  def home():
 
34
  "Content-Type": "application/json",
35
  }
36
 
37
+ # (1) UPDATED: Cohere v2 Chat endpoint
38
+ COHERE_API_URL = 'https://api.cohere.com/v2/chat'
 
 
 
 
 
 
 
 
 
 
39
 
40
+ def _extract_text_v2(resp_json: dict) -> str:
41
+ """
42
+ v2 /chat returns:
43
+ { "message": { "content": [ { "type": "text", "text": "..." } ] } }
44
+ """
45
+ msg = resp_json.get("message", {})
46
+ content = msg.get("content", [])
47
+ if isinstance(content, list) and content:
48
+ block = content[0]
49
+ if isinstance(block, dict):
50
+ return (block.get("text") or "").strip()
51
+ return ""
52
 
53
  def validate_topic(topic):
 
54
  validation_prompt = f"""
55
  ou are a highly knowledgeable AI grammar expert. Your task is to evaluate whether the given topic relates to **English grammar** or not.
56
 
 
71
  No extra text or explanation.
72
  """
73
 
 
 
 
 
 
 
 
 
 
74
  headers = _cohere_headers()
75
  if not headers:
76
  return "Error: COHERE_API_KEY not set"
77
 
78
+ # (2) UPDATED: messages payload
79
  payload = {
80
  'model': 'command-r-08-2024',
81
+ 'messages': [
82
+ {'role': 'user', 'content': validation_prompt}
83
+ ],
84
+ 'max_tokens': 5
85
  }
86
 
87
  try:
88
  response = requests.post(COHERE_API_URL, json=payload, headers=headers)
89
+ # (3) UPDATED: v2 parsing
90
+ validation_result = _extract_text_v2(response.json())
 
 
 
91
 
92
+ if validation_result not in ["Grammar", "Not Grammar", "ask grammar topics"]:
93
+ return "Not Grammar"
94
  return validation_result
95
 
96
  except Exception as e:
97
  return f"Error: {str(e)}"
98
 
99
  @questions_bp.post('/generate-questions')
 
100
  def generate_questions_test():
101
  try:
102
  data = request.get_json()
103
+ topic = data.get('topic', '').strip()
 
 
 
104
  validation_result = validate_topic(topic)
105
 
106
  if validation_result != "Grammar":
107
  return jsonify({"message": "Please enter a valid **grammar topic**, not a general word or unrelated question."}), 400
108
 
 
109
  difficulty = data.get('difficulty', 'basic')
 
 
 
110
  print(f"Generating {difficulty} questions for topic: {topic}")
111
 
 
 
112
  if difficulty == 'basic':
113
  prompt = f"""
114
  Generate five **completely new and unique** very basic-level fill-in-the-blank grammar questions **every time** on the topic '{topic}'.
 
123
  - Each question must include the correct answer in parentheses at the end.
124
  - Do not include any explanations or instructions—only the five questions.
125
  """
 
126
  elif difficulty == 'intermediate':
127
  prompt = f"""
128
  Generate five **completely new and unique** intermediate-level fill-in-the-blank grammar questions **every time** on the topic '{topic}'.
 
137
  - Each question must include the correct answer in parentheses at the end.
138
  - Do not include any explanations or instructions—only the five questions.
139
  """
 
140
  elif difficulty == 'expert':
141
  prompt = f"""
142
  Generate five **completely new and unique** advanced-level (C1) fill-in-the-blank grammar questions **every time** on the topic '{topic}'.
 
151
  - Each question must include the correct answer in parentheses at the end.
152
  - Do not include any explanations or instructions—only the five questions.
153
  """
 
 
 
154
  else:
155
  return jsonify({"error": "Invalid difficulty level"}), 400
156
 
 
 
 
 
157
  headers = _cohere_headers()
158
  if not headers:
159
  return jsonify({"error": "COHERE_API_KEY not set on the server"}), 500
160
 
161
+ # (2) UPDATED: messages payload
162
  payload = {
163
+ 'model': 'command-r-08-2024',
164
+ 'messages': [
165
+ {'role': 'user', 'content': prompt}
166
+ ],
167
+ 'max_tokens': 1000
168
  }
169
 
 
170
  response = requests.post(COHERE_API_URL, json=payload, headers=headers)
 
 
171
  print("Response status code:", response.status_code)
172
  print("Response content:", response.text)
173
 
174
  if response.status_code == 200:
175
+ # (3) UPDATED: v2 parsing
176
+ text = _extract_text_v2(response.json())
177
+ # Return same style as before but adapted (text content)
178
+ return jsonify({"text": text})
179
  else:
180
  return jsonify({"error": "Failed to fetch questions", "details": response.text}), 500
181
  except Exception as e:
182
  return jsonify({"error": str(e)}), 500
183
 
 
184
  @questions_bp.post('/validate-answer')
 
185
  def validate_answer():
186
  try:
 
187
  data = request.get_json()
188
+ topic = data.get('topic', '')
189
  question = data.get('question', '')
190
  user_answer = data.get('user_answer', '')
191
 
 
192
  if not question or not user_answer or not topic:
193
+ return jsonify({'error': 'Topic, question, and user answer are required'}), 400
194
 
 
195
  prompt = f"""
196
  You are a highly knowledgeable grammar assistant. Validate whether the user's answer to the following question is correct or not based on {topic}. If the answer is incorrect, provide a helpful hint.
197
 
 
202
  Is the answer correct? If not, please explain why and give a hint.
203
  """
204
 
 
 
 
 
 
 
205
  headers = _cohere_headers()
206
  if not headers:
207
  return jsonify({"error": "COHERE_API_KEY not set on the server"}), 500
208
 
209
+ # (2) UPDATED: messages payload
210
  payload = {
211
+ 'model': 'command-r-08-2024',
212
+ 'messages': [
213
+ {'role': 'user', 'content': prompt}
214
+ ],
215
  'max_tokens': 100,
216
  'temperature': 0.7
217
  }
218
 
 
219
  response = requests.post(COHERE_API_URL, headers=headers, json=payload)
 
 
220
  print(f"Status Code: {response.status_code}")
221
  print(f"Response Body: {response.text}")
222
 
 
223
  if response.status_code == 200:
224
+ # (3) UPDATED: v2 parsing
225
+ text = _extract_text_v2(response.json())
226
+ return jsonify({"text": text})
227
  else:
228
  return jsonify({'error': 'Failed to fetch data from Cohere API'}), 500
229
 
230
  except Exception as e:
231
  return jsonify({'error': str(e)}), 500
232
 
 
 
 
 
233
  # Function to validate an individual answer using Cohere API
234
  def validate_answer_with_ai(topic, question, user_answer):
235
  try:
 
236
  prompt = f"""
237
  You are a highly knowledgeable grammar assistant. Validate whether the user's answer to the following question is correct or not based on {topic}. If the answer is incorrect, provide a helpful hint.
238
 
 
243
  Is the answer correct? If not, please explain why and give a hint.
244
  """
245
 
 
 
 
 
 
 
246
  headers = _cohere_headers()
247
  if not headers:
248
  return "Error: COHERE_API_KEY not set"
249
 
250
+ # (2) UPDATED: messages payload
251
  payload = {
252
+ 'model': 'command-r-08-2024',
253
+ 'messages': [
254
+ {'role': 'user', 'content': prompt}
255
+ ],
256
  'max_tokens': 200,
257
+ 'temperature': 0.7
 
258
  }
259
 
260
+ # (1) UPDATED URL used here too
261
+ response = requests.post(COHERE_API_URL, headers=headers, json=payload)
262
 
263
  if response.status_code == 200:
264
+ # (3) UPDATED: v2 parsing
265
+ return _extract_text_v2(response.json())
 
 
266
  else:
267
  return f"Error: {response.status_code} - {response.text}"
268
 
269
  except Exception as e:
270
  return f"An error occurred: {str(e)}"
271
 
 
 
272
  @questions_bp.post('/validate-all-answers')
 
 
273
  def validate_all_answers():
274
  try:
 
275
  data = request.get_json()
276
  questions = data.get('questions', [])
277
 
 
280
 
281
  validation_results = []
282
 
 
283
  for item in questions:
284
  topic = item.get('topic', '')
285
  question = item.get('question', '')
 
292
  })
293
  continue
294
 
 
295
  validation_response = validate_answer_with_ai(topic, question, user_answer)
296
 
 
297
  hint = None
298
+ if isinstance(validation_response, str) and (
299
+ "incorrect" in validation_response.lower() or "not correct" in validation_response.lower()
300
+ ):
301
  hint = generate_hint(topic, question, user_answer)
302
 
303
  validation_results.append({
304
  'question': question,
305
  'user_answer': user_answer,
306
  'validation_response': validation_response,
307
+ 'hint': hint
308
  })
309
 
310
  return jsonify({'results': validation_results})
 
312
  except Exception as e:
313
  return jsonify({'error': str(e)}), 500
314
 
 
 
315
  def generate_hint(topic, question, user_answer):
316
  try:
 
317
  prompt = f"""
318
  You are a highly skilled grammar assistant. Your task is to generate a helpful hint for the user to improve their answer based on the following question.
319
 
 
330
  Please make sure the hint is **clear** and **helpful** for the user, **without revealing the correct answer**.
331
  """
332
 
 
 
 
 
 
333
  headers = _cohere_headers()
334
  if not headers:
335
  return "Error: COHERE_API_KEY not set"
336
 
337
+ # (2) UPDATED: messages payload
338
  payload = {
339
+ 'model': 'command-r-08-2024',
340
+ 'messages': [
341
+ {'role': 'user', 'content': prompt}
342
+ ],
343
+ 'max_tokens': 250,
344
+ 'temperature': 0.7
345
  }
346
 
 
347
  response = requests.post(COHERE_API_URL, headers=headers, json=payload)
348
 
349
  if response.status_code == 200:
350
+ # (3) UPDATED: v2 parsing
351
+ return _extract_text_v2(response.json())
 
 
352
  else:
353
  return f"Error: {response.status_code} - {response.text}"
354
 
355
  except Exception as e:
356
  return f"An error occurred: {str(e)}"
357
 
 
358
  if __name__ == '__main__':
359
+ app.register_blueprint(questions_bp, url_prefix='') # local exposure
 
360
  app.run(host='0.0.0.0', port=5012, debug=True)