Patched backend eval

This commit is contained in:
Carlos-Mesquita
2024-11-26 09:08:12 +00:00
parent 6e0276b79d
commit 47cdfe1478
9 changed files with 47 additions and 21 deletions

View File

@@ -10,8 +10,10 @@ from dotenv import load_dotenv
from sentence_transformers import SentenceTransformer from sentence_transformers import SentenceTransformer
from app.repositories.impl import * from app.repositories.impl import *
from app.repositories.impl.document_stores.mongo import MongoDB
from app.services.impl import * from app.services.impl import *
from app.controllers.impl import * from app.controllers.impl import *
from app.services.impl.exam.evaluation import EvaluationService
load_dotenv() load_dotenv()
@@ -67,8 +69,8 @@ class DependencyInjector:
cred = credentials.Certificate(os.getenv("GOOGLE_APPLICATION_CREDENTIALS")) cred = credentials.Certificate(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
firebase_token = cred.get_access_token().access_token firebase_token = cred.get_access_token().access_token
self._container.document_store = providers.Object( self._container.document_store = providers.Factory(
AsyncIOMotorClient(os.getenv("MONGODB_URI"))[os.getenv("MONGODB_DB")] MongoDB, mongo_db=AsyncIOMotorClient(os.getenv("MONGODB_URI"))[os.getenv("MONGODB_DB")]
) )
self._container.firebase_instance = providers.Factory( self._container.firebase_instance = providers.Factory(
@@ -126,11 +128,17 @@ class DependencyInjector:
UserService, document_store=self._container.document_store UserService, document_store=self._container.document_store
) )
self._container.evaluation_service = providers.Factory(
EvaluationService, db=self._container.document_store,
writing_service=self._container.writing_service,
speaking_service=self._container.speaking_service
)
def _setup_controllers(self): def _setup_controllers(self):
self._container.grade_controller = providers.Factory( self._container.grade_controller = providers.Factory(
GradeController, grade_service=self._container.grade_service, GradeController, grade_service=self._container.grade_service,
speaking_service=self._container.speaking_service, evaluation_service=self._container.evaluation_service
writing_service=self._container.writing_service
) )
self._container.user_controller = providers.Factory( self._container.user_controller = providers.Factory(

View File

@@ -8,7 +8,7 @@ class IGradeController(ABC):
@abstractmethod @abstractmethod
async def grade_writing_task( async def grade_writing_task(
self, session_id: str, exercise_id: str, self,
task: int, dto: any, task: int, dto: any,
background_tasks: BackgroundTasks background_tasks: BackgroundTasks
): ):

View File

@@ -23,21 +23,22 @@ class GradeController(IGradeController):
self._logger = logging.getLogger(__name__) self._logger = logging.getLogger(__name__)
async def grade_writing_task( async def grade_writing_task(
self, session_id: str, exercise_id: str, self,
task: int, dto: WritingGradeTaskDTO, background_tasks: BackgroundTasks task: int, dto: WritingGradeTaskDTO, background_tasks: BackgroundTasks
): ):
await self._evaluation_service.create_or_update_evaluation( await self._evaluation_service.create_evaluation(
dto.sessionId, dto.exercise_id, EvaluationType.WRITING, task dto.userId, dto.sessionId, dto.exerciseId, EvaluationType.WRITING, task
) )
await self._evaluation_service.begin_evaluation( await self._evaluation_service.begin_evaluation(
session_id, task, exercise_id, EvaluationType.WRITING, dto, background_tasks dto.userId, dto.sessionId, task, dto.exerciseId, EvaluationType.WRITING, dto, background_tasks
) )
return Response(status_code=200) return Response(status_code=200)
async def grade_speaking_task(self, task: int, form: FormData, background_tasks: BackgroundTasks): async def grade_speaking_task(self, task: int, form: FormData, background_tasks: BackgroundTasks):
answers: Dict[int, Dict] = {} answers: Dict[int, Dict] = {}
user_id = form.get("userId")
session_id = form.get("sessionId") session_id = form.get("sessionId")
exercise_id = form.get("exerciseId") exercise_id = form.get("exerciseId")
@@ -79,12 +80,12 @@ class GradeController(IGradeController):
ex_type = EvaluationType.SPEAKING if task == 2 else EvaluationType.SPEAKING_INTERACTIVE ex_type = EvaluationType.SPEAKING if task == 2 else EvaluationType.SPEAKING_INTERACTIVE
await self._evaluation_service.create_or_update_evaluation( await self._evaluation_service.create_evaluation(
session_id, exercise_id, ex_type, task user_id, session_id, exercise_id, ex_type, task
) )
await self._evaluation_service.begin_evaluation( await self._evaluation_service.begin_evaluation(
session_id, task, exercise_id, ex_type, items, background_tasks user_id, session_id, task, exercise_id, ex_type, items, background_tasks
) )
return Response(status_code=200) return Response(status_code=200)

View File

@@ -2,7 +2,8 @@ from pydantic import BaseModel
class WritingGradeTaskDTO(BaseModel): class WritingGradeTaskDTO(BaseModel):
userId: str
sessionId: str sessionId: str
exerciseId: str
question: str question: str
answer: str answer: str
exercise_id: str

View File

@@ -55,8 +55,7 @@ class FirebaseStorage(IFileStorage):
if response.status_code == 200: if response.status_code == 200:
self._logger.info(f"File {source_file_name} uploaded to {self._storage_url}/o/{destination_blob_name}.") self._logger.info(f"File {source_file_name} uploaded to {self._storage_url}/o/{destination_blob_name}.")
# TODO: Test this await self.make_public(destination_blob_name)
#await self.make_public(destination_blob_name)
file_url = f"{self._storage_url}/o/{destination_blob_name}" file_url = f"{self._storage_url}/o/{destination_blob_name}"
return file_url return file_url

View File

@@ -10,6 +10,7 @@ class IEvaluationService(ABC):
@abstractmethod @abstractmethod
async def create_evaluation( async def create_evaluation(
self, self,
user_id: str,
session_id: str, session_id: str,
exercise_id: str, exercise_id: str,
eval_type: EvaluationType, eval_type: EvaluationType,
@@ -20,7 +21,7 @@ class IEvaluationService(ABC):
@abstractmethod @abstractmethod
async def begin_evaluation( async def begin_evaluation(
self, self,
session_id: str, task: int, user_id: str, session_id: str, task: int,
exercise_id: str, exercise_type: str, exercise_id: str, exercise_type: str,
solution: any, solution: any,
background_tasks: BackgroundTasks background_tasks: BackgroundTasks

View File

@@ -20,6 +20,7 @@ class EvaluationService(IEvaluationService):
async def create_evaluation( async def create_evaluation(
self, self,
user_id: str,
session_id: str, session_id: str,
exercise_id: str, exercise_id: str,
eval_type: EvaluationType, eval_type: EvaluationType,
@@ -28,6 +29,7 @@ class EvaluationService(IEvaluationService):
await self._db.save_to_db( await self._db.save_to_db(
"evaluation", "evaluation",
{ {
"user": user_id,
"session_id": session_id, "session_id": session_id,
"exercise_id": exercise_id, "exercise_id": exercise_id,
"type": eval_type, "type": eval_type,
@@ -38,20 +40,20 @@ class EvaluationService(IEvaluationService):
async def begin_evaluation( async def begin_evaluation(
self, self,
session_id: str, task: int, user_id: str, session_id: str, task: int,
exercise_id: str, exercise_type: str, exercise_id: str, exercise_type: str,
solution: Union[WritingGradeTaskDTO, List[GradeSpeakingItem]], solution: Union[WritingGradeTaskDTO, List[GradeSpeakingItem]],
background_tasks: BackgroundTasks background_tasks: BackgroundTasks
): ):
background_tasks.add_task( background_tasks.add_task(
self._begin_evaluation, self._begin_evaluation,
session_id, task, user_id, session_id, task,
exercise_id, exercise_type, exercise_id, exercise_type,
solution solution
) )
async def _begin_evaluation( async def _begin_evaluation(
self, session_id: str, task: int, self, user_id: str, session_id: str, task: int,
exercise_id: str, exercise_type: str, exercise_id: str, exercise_type: str,
solution: Union[WritingGradeTaskDTO, List[GradeSpeakingItem]] solution: Union[WritingGradeTaskDTO, List[GradeSpeakingItem]]
): ):
@@ -71,6 +73,7 @@ class EvaluationService(IEvaluationService):
await self._db.update( await self._db.update(
"evaluation", "evaluation",
{ {
"user": user_id,
"exercise_id": exercise_id, "exercise_id": exercise_id,
"session_id": session_id, "session_id": session_id,
}, },
@@ -87,6 +90,7 @@ class EvaluationService(IEvaluationService):
await self._db.update( await self._db.update(
"evaluation", "evaluation",
{ {
"user": user_id,
"exercise_id": exercise_id, "exercise_id": exercise_id,
"session_id": session_id "session_id": session_id
}, },

View File

@@ -1,6 +1,8 @@
import asyncio import asyncio
import logging import logging
import os import os
from uuid import uuid4
import aiofiles import aiofiles
import re import re
import uuid import uuid
@@ -249,7 +251,17 @@ class SpeakingService(ISpeakingService):
response['perfect_answer'] = perfect_answers[0]["answer"] response['perfect_answer'] = perfect_answers[0]["answer"]
solutions = []
for file_name in temp_files:
solutions.append(await self._file_storage.upload_file_firebase_get_url(f'{FilePaths.FIREBASE_SPEAKING_VIDEO_FILES_PATH}{uuid4()}.wav', file_name))
response["overall"] = self._fix_speaking_overall(response["overall"], response["task_response"]) response["overall"] = self._fix_speaking_overall(response["overall"], response["task_response"])
response["solutions"] = solutions
if task in {1,3}:
response["answer"] = solutions
else:
response["fullPath"] = solutions[0]
self._log(task, request_id, f'Final response: {response}') self._log(task, request_id, f'Final response: {response}')
return response return response
@@ -266,7 +278,7 @@ class SpeakingService(ISpeakingService):
@staticmethod @staticmethod
async def save_file(item: GradeSpeakingItem) -> str: async def save_file(item: GradeSpeakingItem) -> str:
sound_file_name = FilePaths.AUDIO_FILES_PATH + str(uuid.uuid4()) sound_file_name = "tmp/" + str(uuid.uuid4())
content = await item.answer.read() content = await item.answer.read()
async with aiofiles.open(sound_file_name, 'wb') as f: async with aiofiles.open(sound_file_name, 'wb') as f:
await f.write(content) await f.write(content)

View File

@@ -26,7 +26,7 @@ class OpenAIWhisper(ISpeechToTextService):
self._is_closed = False self._is_closed = False
for i in range(num_models): for i in range(num_models):
self._models[i] = whisper.load_model(self._model_name) self._models[i] = whisper.load_model(self._model_name, in_memory=True)
self._executor = ThreadPoolExecutor( self._executor = ThreadPoolExecutor(
max_workers=num_models, max_workers=num_models,