scn-consultation-api / consultation_api.py
SS-2005's picture
Update consultation_api.py
943e28e verified
Raw
History Blame Contribute Delete
3.96 kB
import logging
import os
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse,RedirectResponse
import boto3
from pydantic import BaseModel
from src.state import VideoGenerationState
from src.nodes.consultation.consultation_pipeline import ConsultationPipelineNode
app = FastAPI(
title="Consultation Video API",
version="1.0.0"
)
logger = logging.getLogger(__name__)
LATEST_CONSULTATION_VIDEOS: dict[str, str] = {}
S3_BUCKET = "tech-learn-state"
s3_client = boto3.client("s3")
class ConsultationRequest(BaseModel):
user_id: str
@app.get("/")
def health():
return {
"status": "healthy",
"service": "consultation-api"
}
@app.post("/consultation-video")
def generate_consultation(req: ConsultationRequest):
try:
state = VideoGenerationState(
session_id=req.user_id,
topic="Consultation",
target_language="english",
tts_gender="female",
optional_params={
"script_type": "consultation"
}
)
node = ConsultationPipelineNode()
result = node.generate_consultation_video(state)
video_value = result.slide_video_path
local_video_path = None
if isinstance(video_value, dict):
local_video_path = video_value.get("english")
if local_video_path is None and video_value:
local_video_path = next(iter(video_value.values()))
elif isinstance(video_value, str):
local_video_path = video_value
if local_video_path and os.path.exists(local_video_path):
LATEST_CONSULTATION_VIDEOS[req.user_id] = local_video_path
return {
"status": result.status,
"user_id": req.user_id,
"video_url": result.slide_video_path,
"download_url": f"/consultation-video/download/{req.user_id}" if local_video_path else None,
"error": result.error
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=str(e)
)
@app.get("/consultation-video/download/{user_id}")
def download_consultation_video(user_id: str):
s3_key = (
f"video_states/{user_id}/"
f"consultation/english/consultation_video.mp4"
)
# Try S3 first (source of truth)
try:
s3_client.head_object(
Bucket=S3_BUCKET,
Key=s3_key
)
presigned_url = s3_client.generate_presigned_url(
"get_object",
Params={
"Bucket": S3_BUCKET,
"Key": s3_key
},
ExpiresIn=3600
)
logger.info(
f"[DOWNLOAD] Serving consultation video from S3 | "
f"user_id={user_id} | key={s3_key}"
)
return RedirectResponse(
url=presigned_url,
status_code=302
)
except Exception as e:
logger.warning(
f"[DOWNLOAD] S3 lookup failed | "
f"user_id={user_id} | key={s3_key} | error={str(e)}"
)
# Fallback to local file
video_path = LATEST_CONSULTATION_VIDEOS.get(user_id)
if video_path and os.path.exists(video_path):
logger.info(
f"[DOWNLOAD] Serving consultation video from local cache | "
f"user_id={user_id} | path={video_path}"
)
return FileResponse(
path=video_path,
media_type="video/mp4",
filename=f"{user_id}_consultation_video.mp4"
)
logger.error(
f"[DOWNLOAD] Consultation video not found anywhere | "
f"user_id={user_id}"
)
raise HTTPException(
status_code=404,
detail=(
f"No consultation video found for user_id '{user_id}'. "
f"Video was not found in S3 and no local copy exists. "
f"Generate the consultation video first."
)
)