Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
148 lines (121 loc) · 4.64 KB
/
Copy pathmain.py
File metadata and controls
148 lines (121 loc) · 4.64 KB
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
import os
import logging
from fastapi import FastAPI, APIRouter, HTTPException, Depends
from pydantic import BaseModel
from typing import List, Optional
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
# Configure logging
logging.basicConfig(level=logging.INFO)
app = FastAPI()
router = APIRouter(prefix="/practice-tests")
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise ValueError("Missing OpenAI API key. Set the OPENAI_API_KEY environment variable.")
# Initialize OpenAI client
def get_openai_client():
client = OpenAI(api_key=api_key)
return client
# Pydantic models
class Question(BaseModel):
question: str
options: List[str]
correct_answer: str
class PracticeTest(BaseModel):
id: Optional[int] = None
title: str
topic: str
questions: List[Question] = []
# In-memory storage for practice tests
practice_tests: List[PracticeTest] = []
practice_test_id_counter = 1
def generate_question(topic: str, client: OpenAI) -> Question:
try:
prompt = (
f"Generate a multiple-choice question about {topic}. "
"Provide 4 options labeled A, B, C, and D. Specify the correct answer as 'Answer: X'."
)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "system", "content": "You are a helpful assistant that generates quiz questions."},
{"role": "user", "content": prompt}],
temperature=0.7
)
generated_text = response.choices[0].message.content
if not generated_text:
raise ValueError("API response is empty.")
logging.info(f"Generated Question:\n{generated_text}")
lines = generated_text.strip().split("\n")
if len(lines) < 6:
raise ValueError("Incomplete question format.")
question_text = lines[0].strip()
options = [line.split(". ", 1)[1].strip() for line in lines[1:5] if ". " in line]
correct_answer_line = lines[-1].strip()
correct_answer = correct_answer_line.split(":")[-1].strip()
if correct_answer not in ["A", "B", "C", "D"]:
raise ValueError("Incorrect answer format.")
return Question(question=question_text, options=options, correct_answer=correct_answer)
except Exception as e:
logging.error(f"Error generating question: {e}")
raise HTTPException(status_code=500, detail=f"Failed to generate question: {str(e)}")
@router.post("/", response_model=PracticeTest)
async def create_practice_test(test: PracticeTest, client: OpenAI = Depends(get_openai_client)):
"""
Creates a new practice test with 5 auto-generated questions.
"""
global practice_test_id_counter
try:
test.id = practice_test_id_counter
test.questions = [generate_question(test.topic, client) for _ in range(5)]
practice_tests.append(test)
practice_test_id_counter += 1
return test
except Exception as e:
logging.error(f"Failed to create practice test: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/", response_model=List[PracticeTest])
async def get_all_practice_tests():
"""
Retrieves all stored practice tests.
"""
return practice_tests
@router.get("/{test_id}", response_model=PracticeTest)
async def get_practice_test(test_id: int):
"""
Retrieves a specific practice test by ID.
"""
for test in practice_tests:
if test.id == test_id:
return test
raise HTTPException(status_code=404, detail="Practice test not found")
@router.put("/{test_id}", response_model=PracticeTest)
async def update_practice_test(test_id: int, updated_test: PracticeTest):
"""
Updates an existing practice test by ID.
"""
for index, test in enumerate(practice_tests):
if test.id == test_id:
updated_test.id = test_id
practice_tests[index] = updated_test
return updated_test
raise HTTPException(status_code=404, detail="Practice test not found")
@router.delete("/{test_id}", response_model=PracticeTest)
async def delete_practice_test(test_id: int):
"""
Deletes a practice test by ID.
"""
for index, test in enumerate(practice_tests):
if test.id == test_id:
removed_test = practice_tests.pop(index)
return removed_test
raise HTTPException(status_code=404, detail="Practice test not found")
# Include router
app.include_router(router)
@app.get("/")
def home():
return {"message": "Welcome to the Practice Tests API"}
# Run the server
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)