Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions src/Components/API/app/routers/species_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,12 @@
from fastapi.responses import JSONResponse
from typing import Optional
from app.database import Predictions
from app.services.model_adapter import MultiModalPredictionError, predict_with_failure_detection
import datetime
import re

router = APIRouter()

# Placeholder prediction
def predict_species(audio_file: UploadFile):
return {
"species": "Crimson Rosella",
"confidence": 0.92
}

@router.post("/predict")
async def predict(
audio: UploadFile = File(...),
Expand All @@ -31,7 +25,10 @@ async def predict(
else:
raise HTTPException(status_code=400, detail="Invalid upload_id format")

prediction = predict_species(audio)
try:
prediction = predict_with_failure_detection(audio)
except MultiModalPredictionError as e:
raise HTTPException(status_code=502, detail=str(e))

# Persist prediction result
try:
Expand Down
44 changes: 44 additions & 0 deletions src/Components/API/app/services/model_adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from numbers import Number
from typing import Any, Dict


class MultiModalPredictionError(Exception):
"""Raised when the multi-modal prediction path fails or returns invalid data."""


def predict_multimodal(audio_file: Any) -> Dict[str, Any]:
# Placeholder until the real multi-modal engine is wired into the adapter.
return {
"species": "Crimson Rosella",
"confidence": 0.92,
}


def validate_prediction_response(result: Any) -> Dict[str, Any]:
if not isinstance(result, dict):
raise MultiModalPredictionError("Multi-modal model returned an invalid response type")

species = result.get("species")
confidence = result.get("confidence")

if not isinstance(species, str) or not species.strip():
raise MultiModalPredictionError("Multi-modal model response is missing a valid species")

if not isinstance(confidence, Number):
raise MultiModalPredictionError("Multi-modal model response is missing a valid confidence")

return {
"species": species,
"confidence": float(confidence),
}


def predict_with_failure_detection(audio_file: Any) -> Dict[str, Any]:
try:
result = predict_multimodal(audio_file)
except MultiModalPredictionError:
raise
except Exception as exc:
raise MultiModalPredictionError("Multi-modal prediction failed") from exc

return validate_prediction_response(result)
Loading