pykara commited on
Commit
6f6b058
·
verified ·
1 Parent(s): fc01712

Update vocabularyBuilder.py

Browse files
Files changed (1) hide show
  1. vocabularyBuilder.py +41 -51
vocabularyBuilder.py CHANGED
@@ -6,6 +6,7 @@ import random
6
  import requests
7
  import json # Add this at the top
8
  import logging
 
9
 
10
  # ---------- Blueprint ----------
11
  vocab_bp = Blueprint("vocab", __name__)
@@ -16,17 +17,12 @@ logging.basicConfig(
16
  format='%(asctime)s - %(levelname)s - %(message)s'
17
  )
18
 
19
-
20
-
21
  app = Flask(__name__)
22
  CORS(app)
23
 
24
- # OpenAI API Key for AI-based validation
25
- # openai.api_key = "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"
26
-
27
- # Cohere API Configuration (for generating vocabulary words)
28
- # COHERE_API_KEY = "WgEAxQyfUXoC3mTTywigL8kNmBH0CmCFtvhdpnC0"
29
- COHERE_API_URL = "https://api.cohere.ai/v1/generate"
30
  _OPENAI_API_KEY_FALLBACK = os.getenv("OPENAI_API_KEY", "")
31
  _COHERE_API_KEY_FALLBACK = os.getenv("COHERE_API_KEY", "")
32
 
@@ -46,22 +42,22 @@ def _cohere_headers():
46
  "Content-Type": "application/json"
47
  }
48
 
49
- @vocab_bp.route('/') # redirect to /vocapp (same behaviour)
50
- # @app.route('/') #Add this route
51
- def root():
52
- return redirect(url_for('home'))
53
-
54
- @vocab_bp.route('/vocapp')
55
- # @app.route('/vocapp')
56
- def home():
57
- return "Welcome to the Flask app! The server is running."
 
 
 
58
 
59
  @vocab_bp.route('/generate-word-association', methods=['GET'])
60
- # @app.route('/generate-word-association', methods=['GET'])
61
  def generate_word_association():
62
  try:
63
- import re
64
-
65
  # -----------------------------
66
  # 1️⃣ Generate Vocabulary Word + 3 Related Words
67
  # -----------------------------
@@ -75,29 +71,27 @@ def generate_word_association():
75
  "options": ["word1", "word2", "word3"]
76
  }
77
  """
 
78
  headers = _cohere_headers()
79
  if not headers:
80
  return jsonify({"error": "COHERE_API_KEY not set"}), 500
81
 
82
- # headers = {
83
- # "Authorization": f"Bearer {COHERE_API_KEY}",
84
- # "Content-Type": "application/json"
85
- # }
86
-
87
  data_related = {
88
  "model": "command-r-08-2024",
89
- "prompt": prompt_related,
 
 
90
  "max_tokens": 100,
91
- "temperature": 1.0,
92
- "stop_sequences": ["}"]
93
  }
94
 
95
- response_related = requests.post(COHERE_API_URL, json=data_related, headers=headers)
96
-
97
- if response_related.status_code != 200 or not response_related.text.strip():
98
  return jsonify({"error": "Failed to generate vocabulary."}), 500
99
 
100
- raw_text = response_related.json().get("generations", [{}])[0].get("text", "").strip()
 
101
  match = re.search(r'\{.*\}', raw_text, re.DOTALL)
102
  if not match:
103
  return jsonify({"error": "Invalid JSON from related words API"}), 500
@@ -123,17 +117,22 @@ def generate_word_association():
123
  }}
124
  """
125
 
 
126
  data_unrelated = {
127
  "model": "command-r-08-2024",
128
- "prompt": prompt_unrelated,
 
 
129
  "max_tokens": 50,
130
- "temperature": 1.0,
131
- "stop_sequences": ["}"]
132
  }
133
 
134
- response_unrelated = requests.post(COHERE_API_URL, json=data_unrelated, headers=headers)
135
- raw_unrelated_text = response_unrelated.json().get("generations", [{}])[0].get("text", "").strip()
136
  match_unrelated = re.search(r'\{.*\}', raw_unrelated_text, re.DOTALL)
 
 
 
137
  json_str_unrelated = match_unrelated.group(0)
138
  unrelated_options = json.loads(json_str_unrelated).get("options", [])
139
 
@@ -147,7 +146,7 @@ def generate_word_association():
147
  random.shuffle(all_options)
148
 
149
  # -----------------------------
150
- # 4️⃣ Generate Image for the Word
151
  # -----------------------------
152
  prompt_image = (
153
  f"A conceptual, symbolic, high-quality illustration representing the meaning of the word '{word}'. "
@@ -155,6 +154,7 @@ def generate_word_association():
155
  )
156
 
157
  try:
 
158
  image_response = openai.images.generate(
159
  model="dall-e-3",
160
  prompt=prompt_image,
@@ -181,11 +181,9 @@ def generate_word_association():
181
  return jsonify({"error": f"Internal Server Error: {str(e)}"}), 500
182
 
183
  # ----------------------------
184
- # 2️⃣ Validate User's Selected Words (Check Correct Answers)
185
  # ----------------------------
186
-
187
  @vocab_bp.route('/validate-selection', methods=['POST'])
188
- # @app.route('/validate-selection', methods=['POST'])
189
  def validate_selection():
190
  try:
191
  data = request.json
@@ -235,7 +233,6 @@ def validate_selection():
235
  feedback_json = json.loads(feedback_text)
236
  structured_feedback = feedback_json.get("feedback", [])
237
 
238
- # Sanity check
239
  if not isinstance(structured_feedback, list):
240
  return jsonify({"error": "Unexpected feedback format from AI."}), 500
241
 
@@ -251,10 +248,9 @@ def validate_selection():
251
  return jsonify({"error": "An error occurred while validating the selection."}), 500
252
 
253
  # ----------------------------
254
- # 3️⃣ Validate User's Sentence Using AI
255
  # ----------------------------
256
  @vocab_bp.route('/validate-sentence', methods=['POST'])
257
- # @app.route('/validate-sentence', methods=['POST'])
258
  def validate_sentence():
259
  try:
260
  data = request.json
@@ -286,7 +282,6 @@ def validate_sentence():
286
  return jsonify({"error": "An error occurred while validating the sentence."}), 500
287
 
288
  @vocab_bp.route('/generate-image', methods=['POST'])
289
- # @app.route('/generate-image', methods=['POST'])
290
  def generate_image():
291
  try:
292
  data = request.json
@@ -295,7 +290,6 @@ def generate_image():
295
  if not word:
296
  return jsonify({"error": "Word is required to generate image"}), 400
297
 
298
- # Adjust prompt to create meaningful, visual examples of the word
299
  prompt = (
300
  f"A conceptual, high-quality illustration that visually explains the word '{word}'. "
301
  "Use realistic or symbolic elements to represent its meaning clearly. No text in the image."
@@ -303,7 +297,7 @@ def generate_image():
303
 
304
  _ensure_openai_key()
305
  response = openai.images.generate(
306
- model="dall-e-3", # or "dall-e-2" if you don’t have access
307
  prompt=prompt,
308
  n=1,
309
  size="1024x1024"
@@ -315,10 +309,6 @@ def generate_image():
315
  except Exception as e:
316
  return jsonify({"error": str(e)}), 500
317
 
318
-
319
- # if __name__ == '__main__':
320
- # app.run(host='0.0.0.0', port=5002, debug=True)
321
-
322
  # ---------- Standalone (local testing) ----------
323
  if __name__ == '__main__':
324
  app = Flask(__name__)
 
6
  import requests
7
  import json # Add this at the top
8
  import logging
9
+ import re # used below
10
 
11
  # ---------- Blueprint ----------
12
  vocab_bp = Blueprint("vocab", __name__)
 
17
  format='%(asctime)s - %(levelname)s - %(message)s'
18
  )
19
 
 
 
20
  app = Flask(__name__)
21
  CORS(app)
22
 
23
+ # Cohere + OpenAI config
24
+ # (1) UPDATED: Cohere v2 Chat endpoint
25
+ COHERE_API_URL = "https://api.cohere.com/v2/chat"
 
 
 
26
  _OPENAI_API_KEY_FALLBACK = os.getenv("OPENAI_API_KEY", "")
27
  _COHERE_API_KEY_FALLBACK = os.getenv("COHERE_API_KEY", "")
28
 
 
42
  "Content-Type": "application/json"
43
  }
44
 
45
+ def _extract_text_v2(resp_json: dict) -> str:
46
+ """
47
+ v2 /chat returns:
48
+ { "message": { "content": [ { "type": "text", "text": "..." } ] } }
49
+ """
50
+ msg = resp_json.get("message", {})
51
+ content = msg.get("content", [])
52
+ if isinstance(content, list) and content:
53
+ block = content[0]
54
+ if isinstance(block, dict):
55
+ return (block.get("text") or "").strip()
56
+ return ""
57
 
58
  @vocab_bp.route('/generate-word-association', methods=['GET'])
 
59
  def generate_word_association():
60
  try:
 
 
61
  # -----------------------------
62
  # 1️⃣ Generate Vocabulary Word + 3 Related Words
63
  # -----------------------------
 
71
  "options": ["word1", "word2", "word3"]
72
  }
73
  """
74
+
75
  headers = _cohere_headers()
76
  if not headers:
77
  return jsonify({"error": "COHERE_API_KEY not set"}), 500
78
 
79
+ # (2) UPDATED: messages payload
 
 
 
 
80
  data_related = {
81
  "model": "command-r-08-2024",
82
+ "messages": [
83
+ {"role": "user", "content": prompt_related}
84
+ ],
85
  "max_tokens": 100,
86
+ "temperature": 1.0
 
87
  }
88
 
89
+ r_related = requests.post(COHERE_API_URL, json=data_related, headers=headers)
90
+ if r_related.status_code != 200 or not r_related.text.strip():
 
91
  return jsonify({"error": "Failed to generate vocabulary."}), 500
92
 
93
+ # (3) UPDATED: v2 parsing
94
+ raw_text = _extract_text_v2(r_related.json())
95
  match = re.search(r'\{.*\}', raw_text, re.DOTALL)
96
  if not match:
97
  return jsonify({"error": "Invalid JSON from related words API"}), 500
 
117
  }}
118
  """
119
 
120
+ # (2) UPDATED: messages payload
121
  data_unrelated = {
122
  "model": "command-r-08-2024",
123
+ "messages": [
124
+ {"role": "user", "content": prompt_unrelated}
125
+ ],
126
  "max_tokens": 50,
127
+ "temperature": 1.0
 
128
  }
129
 
130
+ r_unrelated = requests.post(COHERE_API_URL, json=data_unrelated, headers=headers)
131
+ raw_unrelated_text = _extract_text_v2(r_unrelated.json())
132
  match_unrelated = re.search(r'\{.*\}', raw_unrelated_text, re.DOTALL)
133
+ if not match_unrelated:
134
+ return jsonify({"error": "Invalid JSON from unrelated words API"}), 500
135
+
136
  json_str_unrelated = match_unrelated.group(0)
137
  unrelated_options = json.loads(json_str_unrelated).get("options", [])
138
 
 
146
  random.shuffle(all_options)
147
 
148
  # -----------------------------
149
+ # 4️⃣ Generate Image for the Word (OpenAI — unchanged)
150
  # -----------------------------
151
  prompt_image = (
152
  f"A conceptual, symbolic, high-quality illustration representing the meaning of the word '{word}'. "
 
154
  )
155
 
156
  try:
157
+ _ensure_openai_key()
158
  image_response = openai.images.generate(
159
  model="dall-e-3",
160
  prompt=prompt_image,
 
181
  return jsonify({"error": f"Internal Server Error: {str(e)}"}), 500
182
 
183
  # ----------------------------
184
+ # 2️⃣ Validate User's Selected Words (OpenAI unchanged)
185
  # ----------------------------
 
186
  @vocab_bp.route('/validate-selection', methods=['POST'])
 
187
  def validate_selection():
188
  try:
189
  data = request.json
 
233
  feedback_json = json.loads(feedback_text)
234
  structured_feedback = feedback_json.get("feedback", [])
235
 
 
236
  if not isinstance(structured_feedback, list):
237
  return jsonify({"error": "Unexpected feedback format from AI."}), 500
238
 
 
248
  return jsonify({"error": "An error occurred while validating the selection."}), 500
249
 
250
  # ----------------------------
251
+ # 3️⃣ Validate User's Sentence Using AI (OpenAI — unchanged)
252
  # ----------------------------
253
  @vocab_bp.route('/validate-sentence', methods=['POST'])
 
254
  def validate_sentence():
255
  try:
256
  data = request.json
 
282
  return jsonify({"error": "An error occurred while validating the sentence."}), 500
283
 
284
  @vocab_bp.route('/generate-image', methods=['POST'])
 
285
  def generate_image():
286
  try:
287
  data = request.json
 
290
  if not word:
291
  return jsonify({"error": "Word is required to generate image"}), 400
292
 
 
293
  prompt = (
294
  f"A conceptual, high-quality illustration that visually explains the word '{word}'. "
295
  "Use realistic or symbolic elements to represent its meaning clearly. No text in the image."
 
297
 
298
  _ensure_openai_key()
299
  response = openai.images.generate(
300
+ model="dall-e-3",
301
  prompt=prompt,
302
  n=1,
303
  size="1024x1024"
 
309
  except Exception as e:
310
  return jsonify({"error": str(e)}), 500
311
 
 
 
 
 
312
  # ---------- Standalone (local testing) ----------
313
  if __name__ == '__main__':
314
  app = Flask(__name__)