andevs commited on
Commit
dc017b2
·
verified ·
1 Parent(s): 8a4ecce

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -0
app.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, UploadFile, File, Form
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import JSONResponse
4
+ import json
5
+ import hashlib
6
+ from datetime import datetime, timedelta
7
+ import re
8
+ import logging
9
+
10
+ # Configure logging
11
+ logging.basicConfig(level=logging.INFO)
12
+ logger = logging.getLogger(__name__)
13
+
14
+ # Initialize FastAPI app
15
+ app = FastAPI(
16
+ title="StudyLoop API",
17
+ version="1.0.0",
18
+ description="AI-powered study question generator"
19
+ )
20
+
21
+ # CORS middleware
22
+ app.add_middleware(
23
+ CORSMiddleware,
24
+ allow_origins=["*"],
25
+ allow_credentials=True,
26
+ allow_methods=["*"],
27
+ allow_headers=["*"],
28
+ )
29
+
30
+ # Simple cache
31
+ cache = {}
32
+
33
+ # Health endpoints
34
+ @app.get("/")
35
+ async def root():
36
+ return {"message": "StudyLoop API", "status": "healthy"}
37
+
38
+ @app.get("/health")
39
+ async def health():
40
+ return {"status": "healthy", "timestamp": datetime.now().isoformat()}
41
+
42
+ # Generate mock questions
43
+ def generate_questions(count=5):
44
+ questions = []
45
+ for i in range(count):
46
+ if i % 2 == 0:
47
+ questions.append({
48
+ "id": f"q_{i}",
49
+ "type": "multiple_choice",
50
+ "question": "What is the main topic?",
51
+ "options": ["Option A", "Option B", "Option C", "Option D"],
52
+ "correct_answer": "Option A",
53
+ "explanation": "Based on the text content.",
54
+ "difficulty": "easy",
55
+ "concept": "Main Topic"
56
+ })
57
+ else:
58
+ questions.append({
59
+ "id": f"q_{i}",
60
+ "type": "short_answer",
61
+ "question": "Explain the key concept.",
62
+ "correct_answer": "The key concept is explained in the text.",
63
+ "explanation": "Reference the source material.",
64
+ "difficulty": "medium",
65
+ "concept": "Key Concepts"
66
+ })
67
+ return questions
68
+
69
+ # Main API endpoint
70
+ @app.post("/api/generate")
71
+ async def generate_questions_endpoint(
72
+ text: str = Form(None),
73
+ file: UploadFile = File(None),
74
+ session_id: str = Form(...),
75
+ options: str = Form('{"num_questions": 5}')
76
+ ):
77
+ try:
78
+ # Parse options
79
+ try:
80
+ opts = json.loads(options)
81
+ num_questions = min(opts.get("num_questions", 5), 10)
82
+ except:
83
+ num_questions = 5
84
+
85
+ content = ""
86
+
87
+ # Get content
88
+ if text:
89
+ content = text
90
+ elif file:
91
+ file_bytes = await file.read()
92
+ if len(file_bytes) > 5 * 1024 * 1024:
93
+ raise HTTPException(400, "File too large (max 5MB)")
94
+ try:
95
+ content = file_bytes.decode('utf-8')
96
+ except:
97
+ content = file_bytes.decode('latin-1')
98
+ else:
99
+ raise HTTPException(400, "Provide text or file")
100
+
101
+ # Clean content
102
+ content = re.sub(r'\s+', ' ', content).strip()
103
+
104
+ if len(content) < 10:
105
+ raise HTTPException(400, "Text too short")
106
+
107
+ # Generate questions
108
+ questions = generate_questions(num_questions)
109
+
110
+ # Extract concepts
111
+ concepts = list(set([q.get("concept", "General") for q in questions]))
112
+
113
+ response = {
114
+ "session_id": session_id,
115
+ "concepts": concepts,
116
+ "questions": questions,
117
+ "generated_at": datetime.utcnow().isoformat(),
118
+ "question_count": len(questions)
119
+ }
120
+
121
+ return JSONResponse(response)
122
+
123
+ except HTTPException:
124
+ raise
125
+ except Exception as e:
126
+ logger.error(f"Error: {e}")
127
+ raise HTTPException(500, f"Internal error: {str(e)}")
128
+
129
+ # Generate more questions
130
+ @app.post("/api/generate-more")
131
+ async def generate_more(
132
+ session_id: str = Form(...),
133
+ concepts: str = Form("[]")
134
+ ):
135
+ try:
136
+ # Generate 3 more questions
137
+ questions = generate_questions(3)
138
+ for q in questions:
139
+ q["is_followup"] = True
140
+
141
+ return {
142
+ "session_id": session_id,
143
+ "questions": questions,
144
+ "generated_at": datetime.utcnow().isoformat()
145
+ }
146
+ except Exception as e:
147
+ raise HTTPException(500, str(e))
148
+
149
+ # API info
150
+ @app.get("/api/info")
151
+ async def api_info():
152
+ return {
153
+ "name": "StudyLoop API",
154
+ "version": "1.0.0",
155
+ "endpoints": [
156
+ {"path": "/api/generate", "method": "POST"},
157
+ {"path": "/api/generate-more", "method": "POST"},
158
+ {"path": "/health", "method": "GET"},
159
+ {"path": "/api/info", "method": "GET"}
160
+ ]
161
+ }
162
+
163
+ if __name__ == "__main__":
164
+ import uvicorn
165
+ uvicorn.run(app, host="0.0.0.0", port=7860)