Save speaking asynchronously

This commit is contained in:
Cristiano Ferreira
2023-12-10 15:38:26 +00:00
parent 50c39e5f9c
commit 9f4aed52ae
3 changed files with 91 additions and 63 deletions

80
app.py
View File

@@ -1,14 +1,13 @@
import random
import threading
from flask import Flask, request
from flask_jwt_extended import JWTManager, jwt_required
from functools import reduce
from helper.api_messages import *
from helper.constants import *
from helper.exercises import *
from helper.file_helper import delete_files_older_than_one_day
from helper.firebase_helper import *
from helper.heygen_api import create_video
from helper.heygen_api import create_videos_and_save_to_db
from helper.speech_to_text_helper import *
from helper.token_counter import count_tokens
from helper.openai_interface import make_openai_call, make_openai_instruct_call
@@ -31,6 +30,8 @@ jwt = JWTManager(app)
cred = credentials.Certificate(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
firebase_admin.initialize_app(cred)
thread_event = threading.Event()
@app.route('/healthcheck', methods=['GET'])
def healthcheck():
@@ -158,6 +159,7 @@ def save_listening():
data = request.get_json()
parts = data.get('parts')
template = getListeningTemplate()
id = str(uuid.uuid4())
for i, part in enumerate(parts, start=0):
file_name = str(uuid.uuid4()) + ".mp3"
sound_file_path = AUDIO_FILES_PATH + file_name
@@ -170,7 +172,7 @@ def save_listening():
template["parts"][i]["audio"]["source"] = file_url
template["parts"][i]["exercises"] = part["exercises"]
(result, id) = save_to_db("listening", template)
(result, id) = save_to_db_with_id("listening", template, id)
if result:
return {**template, "id": id}
else:
@@ -292,10 +294,11 @@ def save_writing_task():
data = request.get_json()
exercises = data.get('exercises')
template = getWritingTemplate()
id = str(uuid.uuid4())
for i, exercise in enumerate(exercises, start=0):
template["exercises"][i]["prompt"] = exercise
(result, id) = save_to_db("writing", template)
(result, id) = save_to_db_with_id("writing", template, id)
if result:
return {**template, "id": id}
else:
@@ -524,63 +527,18 @@ def save_speaking():
data = request.get_json()
exercises = data.get('exercises')
template = getSpeakingTemplate()
id = str(uuid.uuid4())
# Speaking 1
sp1_result = create_video(exercises[0]["question"], random.choice(list(AvatarEnum)))
if sp1_result is not None:
sound_file_path = VIDEO_FILES_PATH + sp1_result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp1_result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
sp1_video_path = firebase_file_path
sp1_video_url = url
template["exercises"][0]["text"] = exercises[0]["question"]
template["exercises"][0]["title"] = exercises[0]["topic"]
template["exercises"][0]["video_url"] = sp1_video_url
template["exercises"][0]["video_path"] = sp1_video_path
else:
print("Failed to create video for part 1 question: " + exercises[0]["question"])
thread_event.set()
thread = threading.Thread(
target=create_videos_and_save_to_db,
args=(exercises, template, id),
name=("thread-save-speaking-" + id)
)
thread.start()
# Speaking 2
sp2_result = create_video(exercises[1]["question"], random.choice(list(AvatarEnum)))
if sp2_result is not None:
sound_file_path = VIDEO_FILES_PATH + sp2_result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp2_result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
sp2_video_path = firebase_file_path
sp2_video_url = url
template["exercises"][1]["prompts"] = exercises[1]["prompts"]
template["exercises"][1]["text"] = exercises[1]["question"]
template["exercises"][1]["title"] = exercises[1]["topic"]
template["exercises"][1]["video_url"] = sp2_video_url
template["exercises"][1]["video_path"] = sp2_video_path
else:
print("Failed to create video for part 2 question: " + exercises[1]["question"])
# Speaking 3
sp3_questions = []
avatar = random.choice(list(AvatarEnum))
for question in exercises[2]["questions"]:
result = create_video(question, avatar)
if result is not None:
sound_file_path = VIDEO_FILES_PATH + result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
video = {
"text": question,
"video_path": firebase_file_path,
"video_url": url
}
sp3_questions.append(video)
else:
print("Failed to create video for part 3 question: " + question)
template["exercises"][2]["prompts"] = sp3_questions
template["exercises"][2]["title"] = exercises[2]["topic"]
(result, id) = save_to_db("speaking", template)
if result:
# Return response without waiting for create_videos_and_save_to_db to finish
return {**template, "id": id}
else:
raise Exception("Failed to save speaking: " + template)
except Exception as e:
return str(e)
@@ -677,8 +635,8 @@ def save_reading_passage():
parts = data.get('parts')
template = getReadingTemplate()
template["parts"] = parts
(result, id) = save_to_db("reading", template)
id = str(uuid.uuid4())
(result, id) = save_to_db_with_id("reading", template, id)
if result:
return {**template, "id": id}
else:

View File

@@ -59,4 +59,18 @@ def save_to_db(collection: str, item):
return (False, None)
def save_to_db_with_id(collection: str, item, id: str):
db = firestore.client()
collection_ref = db.collection(collection)
# Reference to the specific document with the desired ID
document_ref = collection_ref.document(id)
# Set the data to the document
document_ref.set(item)
if document_ref:
print(f"Document added with ID: {document_ref.id}")
return (True, document_ref.id)
else:
return (False, None)

View File

@@ -1,9 +1,12 @@
import os
import random
import requests
import time
from dotenv import load_dotenv
from helper.constants import *
from helper.firebase_helper import upload_file_firebase_get_url, save_to_db_with_id
from heygen.AvatarEnum import AvatarEnum
load_dotenv()
@@ -30,6 +33,59 @@ KAYLA_ABBI = "d688099f8db9472cb4890b0561e81793"
JEROME_RYAN = "ad41feb2a5c4483085525e3d8907f512"
TYLER_CHRISTOPHER = "03c796f8ed274bb38f19e893bcbc6121"
def create_videos_and_save_to_db(exercises, template, id):
# Speaking 1
sp1_result = create_video(exercises[0]["question"], random.choice(list(AvatarEnum)))
if sp1_result is not None:
sound_file_path = VIDEO_FILES_PATH + sp1_result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp1_result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
sp1_video_path = firebase_file_path
sp1_video_url = url
template["exercises"][0]["text"] = exercises[0]["question"]
template["exercises"][0]["title"] = exercises[0]["topic"]
template["exercises"][0]["video_url"] = sp1_video_url
template["exercises"][0]["video_path"] = sp1_video_path
else:
print("Failed to create video for part 1 question: " + exercises[0]["question"])
# Speaking 2
sp2_result = create_video(exercises[1]["question"], random.choice(list(AvatarEnum)))
if sp2_result is not None:
sound_file_path = VIDEO_FILES_PATH + sp2_result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp2_result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
sp2_video_path = firebase_file_path
sp2_video_url = url
template["exercises"][1]["prompts"] = exercises[1]["prompts"]
template["exercises"][1]["text"] = exercises[1]["question"]
template["exercises"][1]["title"] = exercises[1]["topic"]
template["exercises"][1]["video_url"] = sp2_video_url
template["exercises"][1]["video_path"] = sp2_video_path
else:
print("Failed to create video for part 2 question: " + exercises[1]["question"])
# Speaking 3
sp3_questions = []
avatar = random.choice(list(AvatarEnum))
for question in exercises[2]["questions"]:
result = create_video(question, avatar)
if result is not None:
sound_file_path = VIDEO_FILES_PATH + result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
video = {
"text": question,
"video_path": firebase_file_path,
"video_url": url
}
sp3_questions.append(video)
else:
print("Failed to create video for part 3 question: " + question)
template["exercises"][2]["prompts"] = sp3_questions
template["exercises"][2]["title"] = exercises[2]["topic"]
save_to_db_with_id("speaking", template, id)
def create_video(text, avatar: AvatarEnum):
# POST TO CREATE VIDEO