Workbook-DB-Server / workbook_server.py
matsuap's picture
Upload 2 files
7c7358d verified
import base64
import uvicorn
from contextlib import asynccontextmanager
import sqlite3
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from openai import OpenAI
import os
# OpenAI APIクライアントを初期化
client = OpenAI()
client.api_key = os.getenv('OPENAI_API_KEY')
@asynccontextmanager
async def lifespan(app: FastAPI):
print("startup event")
yield
print("shutdown event")
app = FastAPI(lifespan=lifespan)
DATABASE = 'workbook.db'
def get_db():
db = getattr(app.state, '_database', None)
if db is None:
db = app.state._database = sqlite3.connect(DATABASE)
return db
@app.get('/api/chapters')
def get_chapters():
db = get_db()
cursor = db.cursor()
cursor.execute("""
SELECT c.chapter, c.chapter_name, COUNT(q.question) as n_questions
FROM chapter c
LEFT JOIN question q ON c.chapter = q.chapter
GROUP BY c.chapter, c.chapter_name
""")
chapters = cursor.fetchall()
chapter_list = [
{
"chapter_number": row[0],
"chapter_name": row[1],
"n_questions": row[2]
} for row in chapters
]
return JSONResponse(content=chapter_list)
class ChapterRequest(BaseModel):
chapter_number: int
@app.post('/api/questions')
def get_questions_by_chapter(request: ChapterRequest):
db = get_db()
cursor = db.cursor()
cursor.execute("SELECT question, options, answer, explain, image FROM question WHERE chapter = ? AND kind = '正誤問題'", (request.chapter_number,))
questions = cursor.fetchall()
if not questions:
raise HTTPException(status_code=404, detail="Questions not found for the given chapter number")
question_list = []
for row in questions:
if row[4] is None:
encoded_string = ''
else:
image_path = os.path.join('./image', row[4])
with open(image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
question_list.append({
"question_text": row[0],
"options": row[1],
"answer": row[2],
"explanation": row[3],
"image": encoded_string,
})
return JSONResponse(content=question_list)
class HintRequest(BaseModel):
question_text: str
options: str
answer: str
@app.post('/api/hint')
def generate_hint(request: HintRequest):
prompt = f"設問: {request.question_text}\n選択肢: {request.options}\n正解: {request.answer}\nこの設問に対するヒントを生成してください。なおレスポンスはヒント文章のみとせよ。冒頭に「ヒント:」などの見出しをつけるな。"
print(prompt)
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": [{'type': 'text', 'text': prompt}],
},
],
)
response_content = response.choices[0].message.content
return JSONResponse(content={"hint": response_content})
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == '__main__':
uvicorn.run(app, host="127.0.0.1", port=8000, log_level="debug")