import os import openai import random from flask import Flask, Blueprint, request, jsonify, current_app from flask_cors import CORS # --- Blueprint --- writting_bp = Blueprint("writting", __name__) app = Flask(__name__) CORS(app) # openai.api_key = "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" # ---- API key from env/config (no hard-coded key) ---- _OPENAI_API_KEY_FALLBACK = os.getenv("OPENAI_API_KEY", "") def _ensure_openai_key(): """Set openai.api_key from app config or env before each API call.""" api_key = (current_app.config.get("OPENAI_API_KEY") if current_app else None) or _OPENAI_API_KEY_FALLBACK if api_key: openai.api_key = api_key previous_topics = set() def is_similar(new_topic): """Check if the new topic is too similar to previously generated ones.""" for topic in previous_topics: if new_topic.lower() in topic.lower() or topic.lower() in new_topic.lower(): return True return False # ---- Routes converted to Blueprint (paths unchanged) ---- @writting_bp.route('/generate-writing-topics', methods=['POST']) # @app.route('/generate-writing-topics', methods=['POST']) def generate_writing_topics(): global previous_topics try: data = request.json grade_level = data.get("grade_level", "lower").lower() valid_levels = {"lower", "middle", "upper"} if grade_level not in valid_levels: return jsonify({"error": "Invalid grade level."}), 400 prompt = f""" Generate a completely **random and unpredictable** writing topic for a {grade_level}-grade student. The topic should: - Be age-appropriate for {grade_level}-grade students. - Be something **new and unexpected**. - Avoid overused or common writing prompts. - Be **appropriate in complexity based on the grade level**: - **For younger students**, make topics more **imaginative and storytelling-driven**. - **For middle-level students**, introduce **more structured thinking, problem-solving, or decision-making elements**. Avoid relying only on fantasy—ensure topics also include **real-world ethical dilemmas, debates, and problem-solving challenges**. - **For upper-level students**, push for **analytical, ethical, or futuristic discussions requiring critical thinking**. - Follow no specific structure or category. - Be **one sentence long**. - **Format the output as:** "Writing topic: " """ # Generate topic with full randomness max_retries = 7 retries = 0 while retries < max_retries: response = openai.chat.completions.create( model="gpt-4-turbo", messages=[{"role": "user", "content": prompt}], max_tokens=50, temperature=1.8, # High randomness for maximum diversity top_p=0.95 # Allows broader AI output ) new_topic = response.choices[0].message.content.strip() # Ensure AI follows correct format if "Writing topic:" in new_topic: new_topic = new_topic.replace("Writing topic:", "").strip() # Check uniqueness before returning if not is_similar(new_topic) and new_topic not in previous_topics: previous_topics.add(new_topic) return jsonify({"topic": new_topic}), 200 retries += 1 return jsonify({"error": "Failed to generate a unique topic"}), 500 except Exception as e: print(f"Error: {e}") return jsonify({"error": "An error occurred"}), 500 @writting_bp.route('/validate-response', methods=['POST']) # @app.route('/validate-response', methods=['POST']) def validate_response(): """ Validate user response against the provided topic using GPT. """ try: data = request.json topic = data.get("topic") response_text = data.get("response") if not topic or not response_text: return jsonify({"error": "Both 'topic' and 'response' fields are required."}), 400 # Define the prompt for GPT to evaluate the response validation_prompt = ( f"You are a strict writing teacher. " f"Score: /10\n\n" f"Check the student's response for grammar, spelling, punctuation, and sentence structure. " f"Give feedback in simple, clear English that a 10-year-old can understand. " f"Keep the feedback neat and easy to read. " f"Use this exact format:\n\n" f"What is good:\n" f"- \n" f"Needs fixing:\n" f"- \n" f"How to improve:\n" f"- \n" f"Topic: '{topic}'. Response: '{response_text}'." ) messages = [ {"role": "system", "content": "You are a helpful writing teacher."}, {"role": "user", "content": validation_prompt} ] # Call GPT for validation using OpenAI's ChatCompletion API result = openai.chat.completions.create( model="gpt-4-turbo", messages=messages, max_tokens=1500, temperature=0.7 ) feedback = result.choices[0].message.content.strip() return jsonify({"feedback": feedback}), 200 except Exception as e: print(f"Error validating response: {e}") return jsonify({"error": "An error occurred while validating the response."}), 500 # if __name__ == '__main__': # app.run(host='0.0.0.0', port=8000, debug=True) # --- Optional: standalone run (local testing) --- if __name__ == '__main__': app = Flask(__name__) CORS(app) app.config["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "") app.register_blueprint(writting_bp, url_prefix='') app.run(host='0.0.0.0', port=8000, debug=True)