Spaces:
Sleeping
Sleeping
File size: 6,288 Bytes
936df9d 83edd7c 936df9d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
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)
|