""" Lyric Background Tasks 가사 생성 관련 백그라운드 태스크를 정의합니다. """ import logging import traceback from sqlalchemy import select from sqlalchemy.exc import SQLAlchemyError from app.database.session import BackgroundSessionLocal from app.lyric.models import Lyric from app.utils.chatgpt_prompt import ChatgptService from app.utils.prompts.prompts import Prompt # 로거 설정 logger = logging.getLogger(__name__) async def _update_lyric_status( task_id: str, status: str, result: str | None = None, ) -> bool: """Lyric 테이블의 상태를 업데이트합니다. Args: task_id: 프로젝트 task_id status: 변경할 상태 ("processing", "completed", "failed") result: 가사 결과 또는 에러 메시지 Returns: bool: 업데이트 성공 여부 """ try: async with BackgroundSessionLocal() as session: query_result = await session.execute( select(Lyric) .where(Lyric.task_id == task_id) .order_by(Lyric.created_at.desc()) .limit(1) ) lyric = query_result.scalar_one_or_none() if lyric: lyric.status = status if result is not None: lyric.lyric_result = result await session.commit() logger.info(f"[Lyric] Status updated - task_id: {task_id}, status: {status}") print(f"[Lyric] Status updated - task_id: {task_id}, status: {status}") return True else: logger.warning(f"[Lyric] NOT FOUND in DB - task_id: {task_id}") print(f"[Lyric] NOT FOUND in DB - task_id: {task_id}") return False except SQLAlchemyError as e: logger.error(f"[Lyric] DB Error while updating status - task_id: {task_id}, error: {e}") print(f"[Lyric] DB Error while updating status - task_id: {task_id}, error: {e}") return False except Exception as e: logger.error(f"[Lyric] Unexpected error while updating status - task_id: {task_id}, error: {e}") print(f"[Lyric] Unexpected error while updating status - task_id: {task_id}, error: {e}") return False async def generate_lyric_background( task_id: str, prompt: Prompt, lyric_input_data: dict, # 프롬프트 메타데이터에서 정의된 Input ) -> None: """백그라운드에서 ChatGPT를 통해 가사를 생성하고 Lyric 테이블을 업데이트합니다. Args: task_id: 프로젝트 task_id prompt: ChatGPT에 전달할 프롬프트 language: 가사 언어 """ import time task_start = time.perf_counter() logger.info(f"[generate_lyric_background] START - task_id: {task_id}") print(f"[generate_lyric_background] ========== START ==========") print(f"[generate_lyric_background] task_id: {task_id}") print(f"[generate_lyric_background] language: {lyric_input_data['language']}") #print(f"[generate_lyric_background] prompt length: {len(prompt)}자") try: # ========== Step 1: ChatGPT 서비스 초기화 ========== step1_start = time.perf_counter() print(f"[generate_lyric_background] Step 1: ChatGPT 서비스 초기화...") # service = ChatgptService( # customer_name="", # 프롬프트가 이미 생성되었으므로 빈 값 # region="", # detail_region_info="", # language=language, # ) chatgpt = ChatgptService() step1_elapsed = (time.perf_counter() - step1_start) * 1000 print(f"[generate_lyric_background] Step 1 완료 ({step1_elapsed:.1f}ms)") # ========== Step 2: ChatGPT API 호출 (가사 생성) ========== step2_start = time.perf_counter() logger.info(f"[generate_lyric_background] Step 2: ChatGPT API 호출 시작 - task_id: {task_id}") print(f"[generate_lyric_background] Step 2: ChatGPT API 호출 시작...") #result = await service.generate(prompt=prompt) result_response = await chatgpt.generate_structured_output(prompt, lyric_input_data) result = result_response['lyric'] step2_elapsed = (time.perf_counter() - step2_start) * 1000 logger.info(f"[generate_lyric_background] Step 2 완료 - 응답 {len(result)}자 ({step2_elapsed:.1f}ms)") print(f"[generate_lyric_background] Step 2 완료 - 응답 {len(result)}자 ({step2_elapsed:.1f}ms)") # ========== Step 3: DB 상태 업데이트 ========== step3_start = time.perf_counter() print(f"[generate_lyric_background] Step 3: DB 상태 업데이트...") await _update_lyric_status(task_id, "completed", result) step3_elapsed = (time.perf_counter() - step3_start) * 1000 print(f"[generate_lyric_background] Step 3 완료 ({step3_elapsed:.1f}ms)") # ========== 완료 ========== total_elapsed = (time.perf_counter() - task_start) * 1000 logger.info(f"[generate_lyric_background] SUCCESS - task_id: {task_id}, 총 소요시간: {total_elapsed:.1f}ms") print(f"[generate_lyric_background] ========== SUCCESS ==========") print(f"[generate_lyric_background] 총 소요시간: {total_elapsed:.1f}ms") print(f"[generate_lyric_background] - Step 1 (서비스 초기화): {step1_elapsed:.1f}ms") print(f"[generate_lyric_background] - Step 2 (GPT API 호출): {step2_elapsed:.1f}ms") print(f"[generate_lyric_background] - Step 3 (DB 업데이트): {step3_elapsed:.1f}ms") except SQLAlchemyError as e: elapsed = (time.perf_counter() - task_start) * 1000 logger.error(f"[generate_lyric_background] DB ERROR - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)") print(f"[generate_lyric_background] DB ERROR - {e} ({elapsed:.1f}ms)") traceback.print_exc() await _update_lyric_status(task_id, "failed", f"Database Error: {str(e)}") except Exception as e: elapsed = (time.perf_counter() - task_start) * 1000 logger.error(f"[generate_lyric_background] EXCEPTION - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)") print(f"[generate_lyric_background] EXCEPTION - {e} ({elapsed:.1f}ms)") traceback.print_exc() await _update_lyric_status(task_id, "failed", f"Error: {str(e)}")