mj-learn-backend / writting.py
Anupriya
writing
83edd7c
raw
history blame
6.29 kB
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: <your topic here>"
"""
# 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: <number>/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"- <two short points about strengths>\n"
f"Needs fixing:\n"
f"- <two short points about mistakes>\n"
f"How to improve:\n"
f"- <one short, clear tip or rewrite>\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)