From 81a74c5f3b9f25f2ec4722b89a4b5ef104337294 Mon Sep 17 00:00:00 2001 From: Cristiano Ferreira Date: Thu, 7 Nov 2024 23:32:44 +0000 Subject: [PATCH 1/2] Update video generation to use heygen. --- app/configs/dependency_injection.py | 2 +- app/services/impl/exam/speaking.py | 15 ++++++++------- app/services/impl/third_parties/heygen.py | 5 +---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/configs/dependency_injection.py b/app/configs/dependency_injection.py index deb9626..d90502c 100644 --- a/app/configs/dependency_injection.py +++ b/app/configs/dependency_injection.py @@ -48,7 +48,7 @@ class DependencyInjector: elai_conf = json.load(file) self._container.vid_gen = providers.Factory( - ELAI, client=self._container.http_client, token=os.getenv("ELAI_TOKEN"), conf=elai_conf + Heygen, client=self._container.http_client, token=os.getenv("HEY_GEN_TOKEN") ) self._container.ai_detector = providers.Factory( GPTZero, client=self._container.http_client, gpt_zero_key=os.getenv("GPT_ZERO_API_KEY") diff --git a/app/services/impl/exam/speaking.py b/app/services/impl/exam/speaking.py index f733537..2615a50 100644 --- a/app/services/impl/exam/speaking.py +++ b/app/services/impl/exam/speaking.py @@ -417,14 +417,14 @@ class SpeakingService(ISpeakingService): return response["fixed_text"] async def create_videos_and_save_to_db(self, exercises, template, req_id): - template = await self._create_video_per_part(exercises, template, 1) - template = await self._create_video_per_part(exercises, template, 2) - template = await self._create_video_per_part(exercises, template, 3) + template = await self._create_video_per_part(exercises, template, 1, req_id) + template = await self._create_video_per_part(exercises, template, 2, req_id) + template = await self._create_video_per_part(exercises, template, 3, req_id) await self._document_store.save_to_db_with_id("speaking", template, req_id) self._logger.info(f'Saved speaking to DB with id {req_id} : {str(template)}') - async def _create_video_per_part(self, exercises: List[Dict], template: Dict, part: int): + async def _create_video_per_part(self, exercises: List[Dict], template: Dict, part: int, req_id: str): avatar = (random.choice(list(ELAIAvatars))).name template_index = part - 1 @@ -441,7 +441,8 @@ class SpeakingService(ISpeakingService): result = await self._create_video( question, avatar, - f'Failed to create video for part {part} question: {str(exercise["question"])}' + f'Failed to create video for part {part} question: {str(exercise["question"])}', + req_id ) if result is not None: video = { @@ -588,8 +589,8 @@ class SpeakingService(ISpeakingService): response["id"] = str(uuid.uuid4()) return response - async def _create_video(self, question: str, avatar: str, error_message: str): - result = await self._vid_gen.create_video(question, avatar) + async def _create_video(self, question: str, avatar: str, error_message: str, title: str): + result = await self._vid_gen.create_video(question, avatar, title) if result is not None: sound_file_path = FilePaths.VIDEO_FILES_PATH + result firebase_file_path = FilePaths.FIREBASE_SPEAKING_VIDEO_FILES_PATH + result diff --git a/app/services/impl/third_parties/heygen.py b/app/services/impl/third_parties/heygen.py index 22d3124..386d326 100644 --- a/app/services/impl/third_parties/heygen.py +++ b/app/services/impl/third_parties/heygen.py @@ -26,10 +26,9 @@ class Heygen(IVideoGeneratorService): self._logger = logging.getLogger(__name__) """ - async def create_video(self, text: str, avatar: str): + async def create_video(self, text: str, avatar: str, title="video_title": str): pass # POST TO CREATE VIDEO - """ create_video_url = 'https://api.heygen.com/v2/template/' + avatar + '/generate' data = { "test": False, @@ -89,5 +88,3 @@ class Heygen(IVideoGeneratorService): else: self._logger.error(f"Failed to download file. Status code: {response.status_code}") return None - """ - From b473b30a758109d3306790bfbd9fe6a5c6043d67 Mon Sep 17 00:00:00 2001 From: Cristiano Ferreira Date: Fri, 8 Nov 2024 19:05:29 +0000 Subject: [PATCH 2/2] Fix video generation --- app/services/abc/third_parties/vid_gen.py | 2 +- app/services/impl/exam/speaking.py | 12 +++++++----- app/services/impl/third_parties/heygen.py | 9 ++++----- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/services/abc/third_parties/vid_gen.py b/app/services/abc/third_parties/vid_gen.py index 5ccaef9..35d9c87 100644 --- a/app/services/abc/third_parties/vid_gen.py +++ b/app/services/abc/third_parties/vid_gen.py @@ -4,5 +4,5 @@ from abc import ABC, abstractmethod class IVideoGeneratorService(ABC): @abstractmethod - async def create_video(self, text: str, avatar: str): + async def create_video(self, text: str, avatar: str, title: str): pass diff --git a/app/services/impl/exam/speaking.py b/app/services/impl/exam/speaking.py index 2615a50..19d92f9 100644 --- a/app/services/impl/exam/speaking.py +++ b/app/services/impl/exam/speaking.py @@ -1,17 +1,17 @@ import logging import os +import random import re import uuid -import random from typing import Dict, List, Optional -from app.repositories.abc import IFileStorage, IDocumentStore -from app.services.abc import ISpeakingService, ILLMService, IVideoGeneratorService, ISpeechToTextService from app.configs.constants import ( FieldsAndExercises, GPTModels, TemperatureSettings, ELAIAvatars, FilePaths ) from app.helpers import TextHelper +from app.repositories.abc import IFileStorage, IDocumentStore +from app.services.abc import ISpeakingService, ILLMService, IVideoGeneratorService, ISpeechToTextService class SpeakingService(ISpeakingService): @@ -462,7 +462,8 @@ class SpeakingService(ISpeakingService): result = await self._create_video( exercise["question"], avatar, - f'Failed to create video for part {part} question: {str(exercise["question"])}' + f'Failed to create video for part {part} question: {str(exercise["question"])}', + req_id ) if result is not None: template["exercises"][template_index]["prompts"] = exercise["prompts"] @@ -503,7 +504,8 @@ class SpeakingService(ISpeakingService): avatar, 'POST - generate_video_{p} - {r} - Failed to create video for part {p} question: {q}'.format( p=part, r=request_id, q=question - ) + ), + request_id ) if result is not None: self._logger.info(f'POST - generate_video_{part} - {request_id} - Video created') diff --git a/app/services/impl/third_parties/heygen.py b/app/services/impl/third_parties/heygen.py index 386d326..6b12915 100644 --- a/app/services/impl/third_parties/heygen.py +++ b/app/services/impl/third_parties/heygen.py @@ -14,19 +14,18 @@ class Heygen(IVideoGeneratorService): def __init__(self, client: AsyncClient, token: str): pass - """ self._get_header = { - 'X-Api-Key': heygen_token + 'X-Api-Key': token } self._post_header = { - 'X-Api-Key': heygen_token, + 'X-Api-Key': token, 'Content-Type': 'application/json' } self._http_client = client self._logger = logging.getLogger(__name__) - """ - async def create_video(self, text: str, avatar: str, title="video_title": str): + + async def create_video(self, text: str, avatar: str, title="video_title"): pass # POST TO CREATE VIDEO create_video_url = 'https://api.heygen.com/v2/template/' + avatar + '/generate'