Spaces:
Running
Running
| import base64 | |
| import json | |
| from fastapi import FastAPI, HTTPException, Depends, Header, Request, Body | |
| from schemas import AudioInput, DetectionResult | |
| from model_service import get_model_service, ModelService | |
| app = FastAPI(title="AI Voice Detection API", version="1.0.0") | |
| async def startup_event(): | |
| # Fixes 504 Timeout | |
| print("API is starting up...") | |
| API_KEY = "my_secret_key_123" | |
| async def verify_api_key(x_api_key: str = Header(...)): | |
| if x_api_key != API_KEY: | |
| raise HTTPException(status_code=401, detail="Invalid API Key") | |
| return x_api_key | |
| async def detect_voice( | |
| request: Request, | |
| payload: dict = Body(..., example={"audioBase64": "PASTE_HERE"}), | |
| service: ModelService = Depends(get_model_service), | |
| api_key: str = Depends(verify_api_key) | |
| ): | |
| try: | |
| audio_b64 = None | |
| # Try JSON first (Portal vs Manual) | |
| try: | |
| body = await request.json() | |
| keys = ["audioBase64", "audio_base_64", "audio", "data", "file"] | |
| for k in keys: | |
| if k in body and body[k]: | |
| audio_b64 = body[k] | |
| break | |
| if not audio_b64: | |
| for v in body.values(): | |
| if isinstance(v, str) and len(v) > 100: | |
| audio_b64 = v | |
| break | |
| except Exception: | |
| # FALLBACK: Handle if the body is just the raw Base64 string | |
| raw_body = await request.body() | |
| audio_b64 = raw_body.decode('utf-8') | |
| if not audio_b64 or len(str(audio_b64)) < 20: | |
| raise HTTPException(status_code=422, detail="No valid audio data.") | |
| # CLEANUP: Remove quotes, spaces, and Data URI prefix | |
| audio_b64 = str(audio_b64).strip().strip('"').strip("'") | |
| if "," in audio_b64: | |
| audio_b64 = audio_b64.split(",")[1] | |
| audio_bytes = base64.b64decode(audio_b64) | |
| except Exception as e: | |
| if isinstance(e, HTTPException): raise e | |
| raise HTTPException(status_code=400, detail=f"Parsing error: {str(e)}") | |
| try: | |
| # Inference (HUMAN or AI_GENERATED) | |
| label, confidence = service.predict(audio_bytes) | |
| return DetectionResult(label=label, confidence=confidence, message="Analysis successful") | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Model error: {str(e)}") | |
| def read_root(): return {"status": "Running"} |