Spaces:
Sleeping
Sleeping
File size: 1,849 Bytes
a162c90 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | # src/expon/presentation/interfaces/rest/controllers/multimodal_controller.py
from fastapi import APIRouter, UploadFile, File, Form, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional, Dict
import os
from tempfile import NamedTemporaryFile
from src.expon.presentation.domain.services.multimodal_service import MultimodalService
# 🔐 Usa la MISMA dependencia de auth del backend
from src.expon.iam.infrastructure.authorization.sfs.auth_bearer import get_current_user
router = APIRouter()
_service = MultimodalService()
class PredictResponse(BaseModel):
dominant_emotion: str
emotion_probabilities: Dict[str, float]
transcript: Optional[str] # ← puede no haber texto
alpha: float
temp_text: float
provider: str
@router.post("/predict", response_model=PredictResponse)
async def predict_multimodal(
audio: UploadFile = File(...),
text: Optional[str] = Form(
None,
description="Texto opcional para fusión. Déjalo vacío para usar solo audio.",
example=None,
),
user=Depends(get_current_user), # ← exige login con tu flujo real
):
# 🔹 Sanitiza el placeholder de Swagger y vacíos
if text is not None:
t = text.strip()
if not t or t.lower() == "string":
text = None
ext = (os.path.splitext(audio.filename or "")[-1] or "").lower()
if ext not in [".wav", ".mp3", ".m4a"]:
raise HTTPException(status_code=400, detail="Formato no soportado (.wav, .mp3, .m4a)")
with NamedTemporaryFile(delete=False, suffix=ext) as tmp:
tmp.write(await audio.read())
tmp_path = tmp.name
try:
result = _service.predict(tmp_path, text)
return PredictResponse(**result)
finally:
try:
os.remove(tmp_path)
except Exception:
pass
|