Spaces:
Sleeping
Sleeping
File size: 3,981 Bytes
b3f89f5 08f0d4c 35456ff 08f0d4c e53bdb6 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 08f0d4c 35456ff 08f0d4c d72a730 08f0d4c 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 2a4d245 b3f89f5 | 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | import os
import sys
# Add project root to sys.path to allow importing 'src'
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
# CRITICAL: Apply compatibility patches BEFORE any speechbrain imports
import torchaudio
if not hasattr(torchaudio, "list_audio_backends"):
def _list_audio_backends():
return ["soundfile"]
torchaudio.list_audio_backends = _list_audio_backends
import huggingface_hub
_original_hf_hub_download = huggingface_hub.hf_hub_download
def _patched_hf_hub_download(*args, **kwargs):
if "use_auth_token" in kwargs:
token_val = kwargs.pop("use_auth_token")
if "token" not in kwargs:
kwargs["token"] = token_val
return _original_hf_hub_download(*args, **kwargs)
huggingface_hub.hf_hub_download = _patched_hf_hub_download
import time
import base64
import traceback
from fastapi import FastAPI, HTTPException, Header, Body
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from pydantic import BaseModel
from dotenv import load_dotenv
# Import the new pipeline
try:
import src
print(f"DEBUG: src module found at {src.__file__}")
from src.pipeline.detector import VoicePipeline
except ImportError as e:
# Fallback or detailed error logging
root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
print(f"Failed to import src.pipeline.detector.")
print(f"CWD: {os.getcwd()}")
print(f"Path: {sys.path}")
print(f"Root dir: {root_path}")
if os.path.exists(root_path):
print(f"Contents of root: {os.listdir(root_path)}")
src_path = os.path.join(root_path, "src")
if os.path.exists(src_path):
print(f"Contents of src: {os.listdir(src_path)}")
raise e
load_dotenv()
app = FastAPI(title="Voice Detector API (Refactored)")
# Initialize Pipeline (Single instance)
# Config path relative to execution root or use absolute
pipeline = VoicePipeline("config/hparams.yaml")
API_KEY = os.getenv("API_KEY", "your-secret-api-key")
class VoiceDetectionRequest(BaseModel):
language: str = "en"
audioFormat: str = "mp3"
audioBase64: str
@app.on_event("startup")
async def startup_event():
# Warmup if needed
pass
@app.post("/api/voice-detection")
async def detect_voice(
x_api_key: str = Header(None),
request_data: VoiceDetectionRequest = Body(...)
):
# 1. API Key Validation
# Allow fallback key for testing if needed
expected_key = os.getenv("API_KEY", "test_key_123")
if x_api_key and x_api_key != expected_key and x_api_key != API_KEY:
raise HTTPException(status_code=403, detail="Invalid API key")
start_time = time.time()
try:
# 2. Decode Audio
try:
audio_bytes = base64.b64decode(request_data.audioBase64, validate=True)
except Exception:
raise HTTPException(status_code=400, detail="Invalid Base64 string")
# 3. Process via Pipeline
result = pipeline.process(audio_bytes)
if "error" in result:
raise HTTPException(status_code=500, detail=result["error"])
# 4. Construct Response
response_payload = {
"status": "success",
"language": request_data.language,
"classification": result["classification"],
"confidenceScore": result["confidenceScore"],
"explanation": result["explanation"],
"processingTime": f"{time.time() - start_time:.2f}s",
"details": result.get("details", {})
}
return JSONResponse(content=response_payload)
except HTTPException as he:
raise he
except Exception as e:
traceback.print_exc()
raise HTTPException(status_code=500, detail=f"Internal Error: {str(e)}")
@app.get("/")
def health_check():
return {"status": "ok", "message": "VoiceGuard API Running (Refactored Structure)"}
|