Files
encoach_backend/app/services/impl/exam/evaluation.py
2024-11-26 09:08:12 +00:00

113 lines
3.5 KiB
Python

import logging
from typing import Union, Dict, List
from fastapi import BackgroundTasks
from app.dtos.evaluation import EvaluationType
from app.dtos.speaking import GradeSpeakingItem
from app.dtos.writing import WritingGradeTaskDTO
from app.repositories.abc import IDocumentStore
from app.services.abc 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
)
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),
}
}
)
async def get_evaluations(self, session_id: str, status: str) -> List[Dict]:
return await self._db.find(
"evaluation",
{
"session_id": session_id,
"status": status
}
)