Save speaking asynchronously
This commit is contained in:
80
app.py
80
app.py
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user