Automated Action 1754fec627 Create Bible Quiz App API with FastAPI and SQLite
- Set up project structure with FastAPI and SQLite
- Create models for users, questions, and quizzes
- Implement Alembic migrations with seed data
- Add user authentication with JWT
- Implement question management endpoints
- Implement quiz creation and management
- Add quiz-taking and scoring functionality
- Set up API documentation and health check endpoint
- Update README with comprehensive documentation
2025-06-03 15:46:44 +00:00

153 lines
4.0 KiB
Python

from typing import List, Optional
from sqlalchemy.orm import Session
from app.models.question import (
BibleBook,
Question,
QuestionCategory,
QuestionDifficulty,
QuestionOption,
)
from app.schemas.question import (
QuestionCreate,
QuestionUpdate,
)
def get_by_id(db: Session, question_id: int) -> Optional[Question]:
"""
Get question by ID
"""
return db.query(Question).filter(Question.id == question_id).first()
def get_multi(
db: Session,
*,
skip: int = 0,
limit: int = 100,
category_id: Optional[int] = None,
difficulty_id: Optional[int] = None,
bible_book_id: Optional[int] = None,
) -> List[Question]:
"""
Get multiple questions with optional filters
"""
query = db.query(Question)
if category_id is not None:
query = query.filter(Question.category_id == category_id)
if difficulty_id is not None:
query = query.filter(Question.difficulty_id == difficulty_id)
if bible_book_id is not None:
query = query.filter(Question.bible_book_id == bible_book_id)
return query.offset(skip).limit(limit).all()
def create(db: Session, *, obj_in: QuestionCreate) -> Question:
"""
Create new question with options
"""
# Extract options from input
options_data = obj_in.options
obj_in_dict = obj_in.dict(exclude={"options"})
# Create question
db_obj = Question(**obj_in_dict)
db.add(db_obj)
db.flush() # Flush to get the ID without committing
# Create options for the question
for option_data in options_data:
option = QuestionOption(
question_id=db_obj.id,
**option_data.dict(),
)
db.add(option)
db.commit()
db.refresh(db_obj)
return db_obj
def update(
db: Session,
*,
db_obj: Question,
obj_in: QuestionUpdate
) -> Question:
"""
Update question and options
"""
# Update question fields
update_data = obj_in.dict(exclude={"options"}, exclude_unset=True)
for field, value in update_data.items():
setattr(db_obj, field, value)
# Update options if provided
if obj_in.options is not None:
# Update existing options or create new ones
existing_options = {opt.id: opt for opt in db_obj.options}
for option_data in obj_in.options:
if hasattr(option_data, "id") and option_data.id in existing_options:
# Update existing option
option = existing_options[option_data.id]
for field, value in option_data.dict(exclude_unset=True).items():
setattr(option, field, value)
else:
# Create new option
option = QuestionOption(
question_id=db_obj.id,
**option_data.dict(exclude={"id"}, exclude_unset=True),
)
db.add(option)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def remove(db: Session, *, question_id: int) -> None:
"""
Delete question (and its options via cascade)
"""
question = db.query(Question).filter(Question.id == question_id).first()
if question:
db.delete(question)
db.commit()
# Functions for managing categories, difficulties, and bible books
def get_all_categories(db: Session) -> List[QuestionCategory]:
"""
Get all question categories
"""
return db.query(QuestionCategory).all()
def get_all_difficulties(db: Session) -> List[QuestionDifficulty]:
"""
Get all question difficulties
"""
return db.query(QuestionDifficulty).all()
def get_all_bible_books(db: Session) -> List[BibleBook]:
"""
Get all Bible books
"""
return db.query(BibleBook).all()
def get_bible_books_by_testament(db: Session, testament: str) -> List[BibleBook]:
"""
Get Bible books by testament (Old or New)
"""
return db.query(BibleBook).filter(BibleBook.testament == testament).all()