import logging from typing import Union, List from fastapi import BackgroundTasks from ielts_be.dtos.evaluation import EvaluationType from ielts_be.dtos.speaking import GradeSpeakingItem from ielts_be.dtos.writing import WritingGradeTaskDTO from ielts_be.repositories import IDocumentStore from ielts_be.services import IWritingService, ISpeakingService, IEvaluationService class EvaluationService(IEvaluationService): def __init__(self, db: IDocumentStore, writing_service: IWritingService, speaking_service: ISpeakingService): self._db = db self._writing_service = writing_service self._speaking_service = speaking_service self._logger = logging.getLogger(__name__) async def create_evaluation( self, user_id: str, session_id: str, exercise_id: str, eval_type: EvaluationType, task: int ): await self._db.save_to_db( "evaluation", { "user": user_id, "session_id": session_id, "exercise_id": exercise_id, "type": eval_type, "task": task, "status": "pending" } ) async def begin_evaluation( self, user_id: str, session_id: str, task: int, exercise_id: str, exercise_type: str, solution: Union[WritingGradeTaskDTO, List[GradeSpeakingItem]], background_tasks: BackgroundTasks ): background_tasks.add_task( self._begin_evaluation, user_id, session_id, task, exercise_id, exercise_type, solution ) async def _begin_evaluation( self, user_id: str, session_id: str, task: int, exercise_id: str, exercise_type: str, solution: Union[WritingGradeTaskDTO, List[GradeSpeakingItem]] ): try: if exercise_type == EvaluationType.WRITING: result = await self._writing_service.grade_writing_task( task, solution.question, solution.answer, solution.attachment ) else: result = await self._speaking_service.grade_speaking_task( task, solution ) await self._db.update( "evaluation", { "user": user_id, "exercise_id": exercise_id, "session_id": session_id, }, { "$set": { "status": "completed", "result": result, } } ) except Exception as e: self._logger.error(f"Error processing evaluation {session_id} - {exercise_id}: {str(e)}") await self._db.update( "evaluation", { "user": user_id, "exercise_id": exercise_id, "session_id": session_id }, { "$set": { "status": "error", "error": str(e), } } )