from fastapi import APIRouter, Depends, HTTPException, Body from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from sqlalchemy.orm import selectinload from uuid import UUID from typing import Any, List from app.db.session import get_db from app.models.shot import Shot as ShotModel from app.models.scene import Scene as SceneModel from app.services.flow_generator import flow_generator router = APIRouter() @router.get("/{shot_id}") async def get_shot( shot_id: UUID, db: AsyncSession = Depends(get_db) ): result = await db.execute( select(ShotModel).where(ShotModel.id == shot_id) ) shot = result.scalars().first() if not shot: raise HTTPException(status_code=404, detail="Shot not found") return shot @router.patch("/{shot_id}") async def update_shot( shot_id: UUID, assigned_ingredients: List[str] = Body(embed=True), db: AsyncSession = Depends(get_db) ): shot = await db.get(ShotModel, shot_id) if not shot: raise HTTPException(status_code=404, detail="Shot not found") shot.assigned_ingredients = assigned_ingredients db.add(shot) await db.commit() await db.refresh(shot) return shot @router.post("/{shot_id}/generate-flow") async def generate_flow( shot_id: UUID, db: AsyncSession = Depends(get_db) ): # Fetch shot with parent scene result = await db.execute( select(ShotModel) .options(selectinload(ShotModel.scene)) .where(ShotModel.id == shot_id) ) shot = result.scalars().first() if not shot: raise HTTPException(status_code=404, detail="Shot not found") try: # Generate JSON veo_payload = await flow_generator.generate_flow_json(shot, shot.scene) # Update Shot shot.veo_json_payload = veo_payload shot.status = "ready" db.add(shot) await db.commit() await db.refresh(shot) return shot.veo_json_payload except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/{shot_id}/refine-flow") async def refine_flow( shot_id: UUID, feedback: str = Body(..., embed=True), db: AsyncSession = Depends(get_db) ): shot = await db.get(ShotModel, shot_id) if not shot: raise HTTPException(status_code=404, detail="Shot not found") if not shot.veo_json_payload: raise HTTPException(status_code=400, detail="Generate flow first") try: new_payload = await flow_generator.refine_flow_json(shot.veo_json_payload, feedback) shot.veo_json_payload = new_payload db.add(shot) await db.commit() await db.refresh(shot) return shot.veo_json_payload except Exception as e: raise HTTPException(status_code=500, detail=str(e))