|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import yaml |
|
|
import logging |
|
|
import uuid |
|
|
from typing import Dict |
|
|
|
|
|
from fastapi import FastAPI, BackgroundTasks, HTTPException |
|
|
|
|
|
|
|
|
import aduc_framework |
|
|
from aduc_framework.types import GenerationState, PreProductionParams, ProductionParams |
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
app = FastAPI( |
|
|
title="ADUC-SDR Framework API", |
|
|
description="API para orquestração de geração de vídeo coerente com IA.", |
|
|
version="3.0.0" |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
with open("config.yaml", 'r') as f: config = yaml.safe_load(f) |
|
|
WORKSPACE_DIR = config['application']['workspace_dir'] |
|
|
|
|
|
aduc = aduc_framework.create_aduc_instance(workspace_dir=WORKSPACE_DIR) |
|
|
|
|
|
logger.info("API FastAPI inicializada e conectada ao Aduc Framework.") |
|
|
except Exception as e: |
|
|
logger.critical(f"ERRO CRÍTICO durante a inicialização da API: {e}", exc_info=True) |
|
|
|
|
|
exit() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tasks_state: Dict[str, GenerationState] = {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_production_in_background(task_id: str, params: ProductionParams): |
|
|
""" |
|
|
Função que executa a tarefa de produção demorada em segundo plano. |
|
|
Ela opera na instância global 'aduc' para modificar seu estado interno. |
|
|
""" |
|
|
logger.info(f"Background task {task_id}: Iniciando produção de vídeo...") |
|
|
try: |
|
|
|
|
|
_, _, final_state = aduc.task_produce_original_movie(params=params) |
|
|
|
|
|
|
|
|
tasks_state[task_id] = final_state |
|
|
logger.info(f"Background task {task_id}: Produção de vídeo concluída com sucesso.") |
|
|
except Exception as e: |
|
|
logger.error(f"Background task {task_id}: Falha na produção. Erro: {e}", exc_info=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/v1/pre-production", response_model=GenerationState, tags=["Workflow"]) |
|
|
async def start_pre_production(params: PreProductionParams): |
|
|
""" |
|
|
Inicia e executa a etapa de pré-produção (storyboard e keyframes). |
|
|
|
|
|
Esta é uma chamada síncrona, pois a pré-produção é relativamente rápida. |
|
|
Ela retorna o estado de geração completo após a conclusão. |
|
|
""" |
|
|
logger.info(f"API: Recebida solicitação de pré-produção com prompt: '{params.prompt[:30]}...'") |
|
|
try: |
|
|
_, _, updated_state = aduc.task_pre_production(params=params) |
|
|
return updated_state |
|
|
except Exception as e: |
|
|
logger.error(f"API: Erro na pré-produção: {e}", exc_info=True) |
|
|
raise HTTPException(status_code=500, detail=f"Erro interno durante a pré-produção: {e}") |
|
|
|
|
|
@app.post("/v1/production", status_code=202, tags=["Workflow"]) |
|
|
async def start_production(params: ProductionParams, background_tasks: BackgroundTasks): |
|
|
""" |
|
|
Inicia a tarefa de produção de vídeo principal em segundo plano. |
|
|
|
|
|
Esta chamada retorna imediatamente com um `task_id`. Use o endpoint |
|
|
`/v1/status/{task_id}` para verificar o progresso e obter o resultado final. |
|
|
""" |
|
|
task_id = str(uuid.uuid4()) |
|
|
logger.info(f"API: Recebida solicitação de produção. Criando tarefa de background com ID: {task_id}") |
|
|
|
|
|
|
|
|
tasks_state[task_id] = aduc.get_current_state() |
|
|
|
|
|
|
|
|
background_tasks.add_task(run_production_in_background, task_id, params) |
|
|
|
|
|
return {"message": "Produção de vídeo iniciada em segundo plano.", "task_id": task_id} |
|
|
|
|
|
@app.get("/v1/status/{task_id}", response_model=GenerationState, tags=["Workflow"]) |
|
|
async def get_task_status(task_id: str): |
|
|
""" |
|
|
Verifica o estado de uma tarefa de geração em andamento ou concluída. |
|
|
""" |
|
|
logger.info(f"API: Verificando status da tarefa {task_id}") |
|
|
state = tasks_state.get(task_id) |
|
|
if not state: |
|
|
raise HTTPException(status_code=404, detail="ID de tarefa não encontrado.") |
|
|
|
|
|
|
|
|
return state |
|
|
|
|
|
@app.get("/health", tags=["Infra"]) |
|
|
async def health_check(): |
|
|
""" |
|
|
Endpoint simples para verificar se a API está online. |
|
|
""" |
|
|
return {"status": "ok"} |