import uvicorn from contextlib import asynccontextmanager import sqlite3 from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse from pydantic import BaseModel @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 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 = [ { "question_text": row[0], "options": row[1], "answer": row[2], "explanation": row[3] } for row in questions ] return JSONResponse(content=question_list) if __name__ == '__main__': uvicorn.run(app, host="127.0.0.1", port=8000, log_level="debug")