deepfake_detection / app /api /routes.py
VoiceGuard Bot
Deploy optimized VoiceGuard with Abhishtagatya model
1c5dd00
Raw
History Blame Contribute Delete
5.81 kB
"""API Routes for VoiceGuard - Matching Hackathon Requirements Exactly.
Endpoint: POST /api/voice-detection
Auth: x-api-key header
Request: {language, audioFormat, audioBase64}
Response: {status, language, classification, confidenceScore, explanation}
"""
import time
from fastapi import APIRouter, HTTPException, Header, UploadFile, File, Form
from typing import Optional
from app.api.schemas import (
VoiceDetectionRequest,
VoiceDetectionResponse,
ErrorResponse,
HealthResponse
)
from app.core.audio_processor import (
audio_processor,
AudioProcessingError,
InvalidBase64Error,
)
from app.core.detector import detector
from app.config import settings
# Create router
router = APIRouter()
# ============== API KEY VALIDATION ==============
def validate_api_key(x_api_key: Optional[str] = Header(None, alias="x-api-key")) -> str:
"""Validate API key from header."""
if not x_api_key:
raise HTTPException(
status_code=401,
detail={"status": "error", "message": "Missing API key. Use x-api-key header."}
)
if x_api_key != settings.API_KEY:
raise HTTPException(
status_code=401,
detail={"status": "error", "message": "Invalid API key"}
)
return x_api_key
# ============== LOGIC HELPER ==============
async def _process_detection_logic(
audio_bytes: bytes,
language: str
) -> VoiceDetectionResponse:
"""Core logic to process audio/bytes and generate response using Hybrid Detector."""
start_time = time.time()
# Step 1: Process audio (bytes → convert → resample to 16kHz)
print(f"📝 Processing audio for language: {language}")
waveform, duration = audio_processor.process_bytes(audio_bytes)
print(f"✅ Audio processed: {duration:.2f}s duration")
# Step 2: Run Detection (HuBERT Model)
print("🔍 Running deepfake detection...")
result = detector.detect(waveform, language=language)
# Calculate processing time
processing_time_ms = int((time.time() - start_time) * 1000)
print(f"⏱️ Total processing time: {processing_time_ms}ms")
# Build response
return VoiceDetectionResponse(
status="success",
language=language.capitalize(),
classification=result.classification,
confidenceScore=round(result.confidence, 2),
explanation=result.explanation
)
# ============== MAIN DETECTION ENDPOINT (Reference Implementation) ==============
# Matches exact hackathon requirements (JSON Base64)
@router.post(
"/voice-detection",
response_model=VoiceDetectionResponse,
responses={
401: {"model": ErrorResponse, "description": "Invalid API key"},
400: {"model": ErrorResponse, "description": "Invalid input"},
500: {"model": ErrorResponse, "description": "Processing error"}
},
summary="Detect AI-Generated Voice (JSON)",
description="Analyze an MP3 audio file (Base64) to detect if it's AI-generated."
)
async def detect_voice_json(
request: VoiceDetectionRequest,
x_api_key: str = Header(..., alias="x-api-key")
):
"""Main detection endpoint (JSON/Base64)."""
validate_api_key(x_api_key)
try:
# Decode base64 to bytes locally to reuse common logic
# audio_processor.decode_base64 raises InvalidBase64Error
audio_bytes = audio_processor.decode_base64(request.audioBase64)
return await _process_detection_logic(audio_bytes, request.language)
except InvalidBase64Error as e:
raise HTTPException(
status_code=400,
detail={"status": "error", "message": f"Invalid Base64 encoding: {str(e)}"}
)
except AudioProcessingError as e:
raise HTTPException(
status_code=400,
detail={"status": "error", "message": str(e)}
)
except Exception as e:
print(f"❌ Error during detection: {e}")
raise HTTPException(
status_code=500,
detail={"status": "error", "message": f"Detection failed: {str(e)}"}
)
# ============== FILE UPLOAD ENDPOINT (For Testing/Ease of Use) ==============
@router.post(
"/voice-detection/file",
response_model=VoiceDetectionResponse,
responses={
401: {"model": ErrorResponse, "description": "Invalid API key"},
400: {"model": ErrorResponse, "description": "Invalid input"},
},
summary="Detect AI-Generated Voice (File Upload)",
description="Upload an audio file (MP3/WAV) to detect if it's AI-generated."
)
async def detect_voice_file(
file: UploadFile = File(..., description="Audio file (MP3/WAV)"),
language: str = Form(..., description="Language: Tamil, English, Hindi, Malayalam, Telugu"),
x_api_key: str = Header(..., alias="x-api-key")
):
"""File upload detection endpoint."""
validate_api_key(x_api_key)
try:
content = await file.read()
return await _process_detection_logic(content, language)
except AudioProcessingError as e:
raise HTTPException(
status_code=400,
detail={"status": "error", "message": str(e)}
)
except Exception as e:
print(f"❌ Error during detection: {e}")
raise HTTPException(
status_code=500,
detail={"status": "error", "message": f"Detection failed: {str(e)}"}
)
# ============== HEALTH CHECK (bonus) ==============
@router.get(
"/health",
response_model=HealthResponse,
summary="Health Check",
description="Check API health and model status"
)
async def health_check():
"""Health check endpoint."""
return HealthResponse(
status="healthy",
model_loaded=detector.is_loaded,
version="1.0.0"
)