Updated this to the latest version of develop, got rid of most of the duplication, might be missing some packages in toml, needs testing

This commit is contained in:
Carlos Mesquita
2024-08-30 02:35:11 +01:00
parent 3cf9fa5cba
commit f92a803d96
73 changed files with 3642 additions and 2703 deletions

View File

@@ -5,6 +5,7 @@ from .speaking import ISpeakingService
from .reading import IReadingService
from .grade import IGradeService
from .training import ITrainingService
from .kb import IKnowledgeBase
from .third_parties import *
__all__ = [

View File

@@ -4,20 +4,10 @@ from typing import Dict, List
class IGradeService(ABC):
@abstractmethod
async def grade_short_answers(self, data: Dict):
pass
@abstractmethod
async def calculate_grading_summary(self, extracted_sections: List):
pass
@abstractmethod
async def _calculate_section_grade_summary(self, section):
pass
@staticmethod
@abstractmethod
def _parse_openai_response(response):
pass
@staticmethod
@abstractmethod
def _parse_bullet_points(bullet_points_str, grade):
pass

10
app/services/abc/kb.py Normal file
View File

@@ -0,0 +1,10 @@
from abc import ABC, abstractmethod
from typing import List, Dict
class IKnowledgeBase(ABC):
@abstractmethod
def query_knowledge_base(self, query: str, category: str, top_k: int = 5) -> List[Dict[str, str]]:
pass

View File

@@ -1,10 +1,19 @@
from abc import ABC, abstractmethod
import random
from typing import Dict
from fastapi import UploadFile
from app.configs.constants import EducationalContent
class ILevelService(ABC):
@abstractmethod
async def get_level_exam(self):
async def get_level_exam(
self, number_of_exercises: int = 25, min_timer: int = 25, diagnostic: bool = False
) -> Dict:
pass
@abstractmethod
@@ -12,13 +21,27 @@ class ILevelService(ABC):
pass
@abstractmethod
async def _gen_multiple_choice_level(self, quantity: int, start_id=1):
async def get_custom_level(self, data: Dict):
pass
@abstractmethod
async def _replace_exercise_if_exists(self, all_exams, current_exercise, current_exam, seen_keys):
async def upload_level(self, upload: UploadFile) -> Dict:
pass
@abstractmethod
async def _generate_single_mc_level_question(self):
async def gen_multiple_choice(
self, mc_variant: str, quantity: int, start_id: int = 1, *, utas: bool = False, all_exams=None
):
pass
@abstractmethod
async def gen_blank_space_text_utas(
self, quantity: int, start_id: int, size: int, topic=random.choice(EducationalContent.MTI_TOPICS)
):
pass
@abstractmethod
async def gen_reading_passage_utas(
self, start_id, sa_quantity: int, mc_quantity: int, topic=random.choice(EducationalContent.MTI_TOPICS)
):
pass

View File

@@ -1,68 +1,18 @@
import queue
from abc import ABC, abstractmethod
from queue import Queue
from typing import Dict
from typing import Dict, List
class IListeningService(ABC):
@abstractmethod
async def generate_listening_question(self, section: int, topic: str) -> Dict:
pass
@abstractmethod
async def generate_listening_exercises(
self, section: int, dialog: str,
req_exercises: list[str], exercises_queue: Queue,
start_id: int, difficulty: str
async def get_listening_question(
self, section_id: int, topic: str, req_exercises: List[str], difficulty: str,
number_of_exercises_q=queue.Queue(), start_id=-1
):
pass
@abstractmethod
async def save_listening(self, parts, min_timer, difficulty):
async def save_listening(self, parts: list[dict], min_timer: int, difficulty: str, listening_id: str) -> Dict:
pass
# ==================================================================================================================
# Helpers
# ==================================================================================================================
@abstractmethod
async def _generate_listening_conversation(self, section: int, topic: str) -> Dict:
pass
@abstractmethod
async def _generate_listening_monologue(self, section: int, topic: str) -> Dict:
pass
@abstractmethod
def _get_conversation_voices(self, response: Dict, unique_voices_across_segments: bool):
pass
@staticmethod
@abstractmethod
def _get_random_voice(gender: str):
pass
@abstractmethod
async def _gen_multiple_choice_exercise_listening(
self, dialog_type: str, text: str, quantity: int, start_id, difficulty
):
pass
@abstractmethod
async def _gen_write_blanks_questions_exercise_listening(
self, dialog_type: str, text: str, quantity: int, start_id, difficulty
):
pass
@abstractmethod
async def _gen_write_blanks_notes_exercise_listening(
self, dialog_type: str, text: str, quantity: int, start_id, difficulty
):
pass
@abstractmethod
async def _gen_write_blanks_form_exercise_listening(
self, dialog_type: str, text: str, quantity: int, start_id, difficulty
):
pass

View File

@@ -2,8 +2,6 @@ from abc import ABC, abstractmethod
from queue import Queue
from typing import List
from app.configs.constants import QuestionType
class IReadingService(ABC):
@@ -14,36 +12,11 @@ class IReadingService(ABC):
topic: str,
req_exercises: List[str],
number_of_exercises_q: Queue,
difficulty: str
):
pass
# ==================================================================================================================
# Helpers
# ==================================================================================================================
@abstractmethod
async def generate_reading_passage(self, q_type: QuestionType, topic: str):
pass
@abstractmethod
async def _generate_reading_exercises(
self, passage: str, req_exercises: list, number_of_exercises_q, start_id, difficulty
difficulty: str,
start_id: int
):
pass
@abstractmethod
async def _gen_summary_fill_blanks_exercise(self, text: str, quantity: int, start_id, difficulty):
pass
@abstractmethod
async def _gen_true_false_not_given_exercise(self, text: str, quantity: int, start_id, difficulty):
pass
@abstractmethod
async def _gen_write_blanks_exercise(self, text: str, quantity: int, start_id, difficulty):
pass
@abstractmethod
async def _gen_paragraph_match_exercise(self, text: str, quantity: int, start_id):
async def generate_reading_passage(self, part: int, topic: str, word_count: int = 800):
pass

View File

@@ -1,21 +1,17 @@
from abc import ABC, abstractmethod
from typing import List, Dict
from typing import List, Dict, Optional
class ISpeakingService(ABC):
@abstractmethod
async def get_speaking_task(self, task_id: int, topic: str, difficulty: str):
async def get_speaking_part(
self, part: int, topic: str, difficulty: str, second_topic: Optional[str] = None
) -> Dict:
pass
@abstractmethod
async def grade_speaking_task_1_and_2(
self, task: int, question: str, answer_firebase_path: str, sound_file_name: str
):
pass
@abstractmethod
async def grade_speaking_task_3(self, answers: Dict, task: int = 3):
async def grade_speaking_task(self, task: int, answers: List[Dict]) -> Dict:
pass
@abstractmethod
@@ -23,35 +19,11 @@ class ISpeakingService(ABC):
pass
@abstractmethod
async def generate_speaking_video(self, original_question: str, topic: str, avatar: str, prompts: List[str]):
pass
@abstractmethod
async def generate_interactive_video(self, questions: List[str], avatar: str, topic: str):
pass
# ==================================================================================================================
# Helpers
# ==================================================================================================================
@staticmethod
@abstractmethod
def _zero_rating(comment: str):
pass
@staticmethod
@abstractmethod
def _calculate_overall(response: Dict):
pass
@abstractmethod
async def _get_speaking_corrections(self, text):
pass
@abstractmethod
async def _create_video_per_part(self, exercises: List[Dict], template: Dict, part: int):
pass
@abstractmethod
async def _create_video(self, question: str, avatar: str, error_message: str):
async def generate_video(
self, part: int, avatar: str, topic: str, questions: list[str],
*,
second_topic: Optional[str] = None,
prompts: Optional[list[str]] = None,
suffix: Optional[str] = None,
):
pass

View File

@@ -1,6 +1,10 @@
from abc import ABC, abstractmethod
from typing import List, Optional
from typing import List, Optional, TypeVar, Callable
from openai.types.chat import ChatCompletionMessageParam
from pydantic import BaseModel
T = TypeVar('T', bound=BaseModel)
class ILLMService(ABC):
@@ -19,3 +23,16 @@ class ILLMService(ABC):
@abstractmethod
async def prediction_override(self, **kwargs):
pass
@abstractmethod
async def pydantic_prediction(
self,
messages: List[ChatCompletionMessageParam],
map_to_model: Callable,
json_scheme: str,
*,
model: Optional[str] = None,
temperature: Optional[float] = None,
max_retries: int = 3
) -> List[T] | T | None:
pass

View File

@@ -1,5 +1,7 @@
from abc import ABC, abstractmethod
from typing import Dict
class ITrainingService(ABC):
@@ -7,7 +9,6 @@ class ITrainingService(ABC):
async def fetch_tips(self, context: str, question: str, answer: str, correct_answer: str):
pass
@staticmethod
@abstractmethod
def _get_question_tips(question: str, answer: str, correct_answer: str, context: str = None):
async def get_training_content(self, training_content: Dict) -> Dict:
pass

View File

@@ -1,6 +1,4 @@
from abc import ABC, abstractmethod
from typing import Dict
class IWritingService(ABC):
@@ -11,22 +9,3 @@ class IWritingService(ABC):
@abstractmethod
async def grade_writing_task(self, task: int, question: str, answer: str):
pass
# ==================================================================================================================
# Helpers
# ==================================================================================================================
@staticmethod
@abstractmethod
def _get_writing_prompt(task: int, topic: str, difficulty: str):
pass
@staticmethod
@abstractmethod
async def _get_fixed_text(self, text):
pass
@staticmethod
@abstractmethod
def _zero_rating(comment: str):
pass