Run_code_api / src /apis /routes /lesson_route.py
ABAO77's picture
Add lesson management functionality with JSON data integration and response models
0f1954e
raw
history blame
5.41 kB
from fastapi import APIRouter, status, Depends, BackgroundTasks, HTTPException
from fastapi.responses import JSONResponse
from src.utils.logger import logger
from pydantic import BaseModel, Field
from typing import List, Dict, Any, Optional
from src.agents.lesson_practice.flow import lesson_practice_agent
from src.apis.models.lesson_models import Lesson, LessonResponse, LessonDetailResponse
import json
import os
import uuid
from datetime import datetime
router = APIRouter(prefix="/lesson", tags=["AI"])
class LessonPracticeRequest(BaseModel):
unit: str = Field(..., description="Unit of the lesson")
vocabulary: list = Field(..., description="Vocabulary for the lesson")
key_structures: list = Field(..., description="Key structures for the lesson")
practice_questions: list = Field(
..., description="Practice questions for the lesson"
)
student_level: str = Field("beginner", description="Student's level of English")
query: str = Field(..., description="User query for the lesson")
session_id: str = Field(..., description="Session ID for the lesson")
# Helper function to load lessons from JSON file
def load_lessons_from_file() -> List[Lesson]:
"""Load lessons from the JSON file"""
try:
lessons_file_path = os.path.join(os.path.dirname(__file__), "..", "..", "data", "lessons.json")
if not os.path.exists(lessons_file_path):
logger.warning(f"Lessons file not found at {lessons_file_path}")
return []
with open(lessons_file_path, 'r', encoding='utf-8') as file:
lessons_data = json.load(file)
# Convert to Lesson objects
lessons = []
for lesson_data in lessons_data:
try:
lesson = Lesson(**lesson_data)
lessons.append(lesson)
except Exception as e:
logger.error(f"Error parsing lesson {lesson_data.get('id', 'unknown')}: {str(e)}")
continue
return lessons
except Exception as e:
logger.error(f"Error loading lessons: {str(e)}")
return []
@router.get("/all", response_model=LessonResponse)
async def get_all_lessons():
"""
Get all available lessons
Returns:
LessonResponse: Contains list of all lessons and total count
"""
try:
lessons = load_lessons_from_file()
return LessonResponse(
lessons=lessons,
total=len(lessons)
)
except Exception as e:
logger.error(f"Error retrieving lessons: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to retrieve lessons"
)
@router.get("/{lesson_id}", response_model=LessonDetailResponse)
async def get_lesson_by_id(lesson_id: str):
"""
Get a specific lesson by ID
Args:
lesson_id (str): The unique identifier of the lesson
Returns:
LessonDetailResponse: Contains the lesson details
"""
try:
lessons = load_lessons_from_file()
# Find the lesson with the specified ID
lesson = next((l for l in lessons if l.id == lesson_id), None)
if not lesson:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Lesson with ID '{lesson_id}' not found"
)
return LessonDetailResponse(lesson=lesson)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error retrieving lesson {lesson_id}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to retrieve lesson"
)
@router.get("/search/unit/{unit_name}")
async def search_lessons_by_unit(unit_name: str):
"""
Search lessons by unit name (case-insensitive partial match)
Args:
unit_name (str): Part of the unit name to search for
Returns:
LessonResponse: Contains list of matching lessons
"""
try:
lessons = load_lessons_from_file()
# Filter lessons by unit name (case-insensitive partial match)
matching_lessons = [
lesson for lesson in lessons
if unit_name.lower() in lesson.unit.lower()
]
return LessonResponse(
lessons=matching_lessons,
total=len(matching_lessons)
)
except Exception as e:
logger.error(f"Error searching lessons by unit '{unit_name}': {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to search lessons"
)
@router.post("/chat")
async def chat(request: LessonPracticeRequest):
response = await lesson_practice_agent().ainvoke(
{
"unit": request.unit,
"vocabulary": request.vocabulary,
"key_structures": request.key_structures,
"practice_questions": request.practice_questions,
"student_level": request.student_level,
"messages": [request.query],
},
{"configurable": {"thread_id": request.session_id}},
)
return JSONResponse(
content=response["messages"][-1].content, status_code=status.HTTP_200_OK
)