Automated Action 53d9909fb6 Create gamified kids learning API with FastAPI and SQLite
- Set up project structure with FastAPI and SQLite
- Implement user authentication with JWT
- Create models for learning content (subjects, lessons, quizzes)
- Add progress tracking and gamification features
- Implement comprehensive API documentation
- Add error handling and validation
- Set up proper logging and health check endpoint
2025-06-17 18:25:16 +00:00

198 lines
6.0 KiB
Python

from __future__ import annotations
from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException, Path, Query, status
from sqlalchemy.orm import Session
from app import models, schemas
from app.api import deps
from app.db.session import get_db
from app.models.achievement import AchievementType
from app.services.achievement import achievement, user_achievement
router = APIRouter()
@router.get("/", response_model=List[schemas.Achievement])
def read_achievements(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
achievement_type: AchievementType = Query(None, description="Filter by achievement type"),
active_only: bool = Query(True, description="Filter only active achievements"),
) -> Any:
"""
Retrieve achievements.
"""
if achievement_type:
achievements = achievement.get_by_type(
db, achievement_type=achievement_type, skip=skip, limit=limit
)
elif active_only:
achievements = achievement.get_active(db, skip=skip, limit=limit)
else:
achievements = achievement.get_multi(db, skip=skip, limit=limit)
return achievements
@router.post("/", response_model=schemas.Achievement)
def create_achievement(
*,
db: Session = Depends(get_db),
achievement_in: schemas.AchievementCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new achievement. Only for superusers.
"""
achievement_obj = achievement.create(db, obj_in=achievement_in)
return achievement_obj
@router.get("/{achievement_id}", response_model=schemas.Achievement)
def read_achievement(
*,
db: Session = Depends(get_db),
achievement_id: int = Path(..., gt=0),
) -> Any:
"""
Get achievement by ID.
"""
achievement_obj = achievement.get(db, id=achievement_id)
if not achievement_obj:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Achievement not found",
)
return achievement_obj
@router.put("/{achievement_id}", response_model=schemas.Achievement)
def update_achievement(
*,
db: Session = Depends(get_db),
achievement_id: int = Path(..., gt=0),
achievement_in: schemas.AchievementUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update achievement. Only for superusers.
"""
achievement_obj = achievement.get(db, id=achievement_id)
if not achievement_obj:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Achievement not found",
)
achievement_obj = achievement.update(db, db_obj=achievement_obj, obj_in=achievement_in)
return achievement_obj
@router.delete("/{achievement_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_achievement(
*,
db: Session = Depends(get_db),
achievement_id: int = Path(..., gt=0),
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> None:
"""
Delete achievement. Only for superusers.
"""
achievement_obj = achievement.get(db, id=achievement_id)
if not achievement_obj:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Achievement not found",
)
achievement.remove(db, id=achievement_id)
@router.get("/user/{user_id}", response_model=List[schemas.UserAchievement])
def read_user_achievements(
*,
db: Session = Depends(get_db),
user_id: int = Path(..., gt=0),
skip: int = 0,
limit: int = 100,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get a user's achievements.
"""
# Regular users can only get their own achievements
if user_id != current_user.id and not current_user.is_superuser:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
)
user_achievements = user_achievement.get_by_user(db, user_id=user_id, skip=skip, limit=limit)
return user_achievements
@router.post("/user/{user_id}/award/{achievement_id}", response_model=schemas.UserAchievement)
def award_achievement_to_user(
*,
db: Session = Depends(get_db),
user_id: int = Path(..., gt=0),
achievement_id: int = Path(..., gt=0),
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Award an achievement to a user. Only for superusers.
"""
# Check if achievement exists
achievement_obj = achievement.get(db, id=achievement_id)
if not achievement_obj:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Achievement not found",
)
# Check if user exists
user = db.query(models.User).filter(models.User.id == user_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found",
)
user_achievement_obj = user_achievement.award_achievement(
db, user_id=user_id, achievement_id=achievement_id
)
return user_achievement_obj
@router.post("/user/{user_id}/check", response_model=List[schemas.UserAchievement])
def check_user_achievements(
*,
db: Session = Depends(get_db),
user_id: int = Path(..., gt=0),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Check and award achievements based on user's progress.
"""
# Regular users can only check their own achievements
if user_id != current_user.id and not current_user.is_superuser:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
)
# Check if user exists
user = db.query(models.User).filter(models.User.id == user_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found",
)
new_achievements = user_achievement.check_achievements(db, user_id=user_id)
return new_achievements