# C:\Users\bahae\.gemini\antigravity\scratch\verivid-ai\backend\app\services\sightengine.py import requests from app.core.config import settings SIGHTENGINE_CHECK_URL = "https://api.sightengine.com/1.0/check.json" def analyze_with_sightengine(image_url: str = None, image_bytes: bytes = None) -> dict: """ Use SightEngine's professional AI detection. Returns: {"ai_score": 0-1, "details": str, "raw": dict} """ if not settings.SIGHTENGINE_USER or not settings.SIGHTENGINE_SECRET: return {"ai_score": None, "details": "SightEngine not configured", "raw": None} try: if image_url: # URL-based check response = requests.post( SIGHTENGINE_CHECK_URL, data={ "url": image_url, "models": "genai", "api_user": settings.SIGHTENGINE_USER, "api_secret": settings.SIGHTENGINE_SECRET }, timeout=30 ) elif image_bytes: # File-based check response = requests.post( SIGHTENGINE_CHECK_URL, data={ "models": "genai", "api_user": settings.SIGHTENGINE_USER, "api_secret": settings.SIGHTENGINE_SECRET }, files={"media": ("image.jpg", image_bytes, "image/jpeg")}, timeout=30 ) else: return {"ai_score": None, "details": "No image provided", "raw": None} if response.status_code != 200: return {"ai_score": None, "details": f"API error: {response.status_code}", "raw": response.text[:200]} data = response.json() # SightEngine returns: {"type": {"ai_generated": 0.95, ...}} if data.get("status") == "success": genai_data = data.get("type", {}) ai_score = genai_data.get("ai_generated", 0) return { "ai_score": ai_score, "details": f"SightEngine AI detection: {round(ai_score * 100)}% AI probability", "raw": data } else: return {"ai_score": None, "details": f"API error: {data.get('error', {}).get('message', 'Unknown')}", "raw": data} except Exception as e: return {"ai_score": None, "details": f"Exception: {str(e)}", "raw": None} def analyze_frames_with_sightengine(frame_paths: list) -> dict: """Analyze multiple frames and aggregate scores""" scores = [] details = [] for path in frame_paths[:5]: # Limit to 5 frames to save API calls try: with open(path, 'rb') as f: img_bytes = f.read() result = analyze_with_sightengine(image_bytes=img_bytes) if result["ai_score"] is not None: scores.append(result["ai_score"]) details.append(f"Frame: {round(result['ai_score'] * 100)}%") except Exception as e: details.append(f"Error: {str(e)[:50]}") if scores: avg_score = sum(scores) / len(scores) max_score = max(scores) return { "avg_score": avg_score, "max_score": max_score, "frame_count": len(scores), "frame_scores": [round(s, 3) for s in scores], "details": f"SightEngine analyzed {len(scores)} frames. Avg: {round(avg_score*100)}%, Max: {round(max_score*100)}%" } else: return { "avg_score": None, "max_score": None, "frame_count": 0, "frame_scores": [], "details": "SightEngine analysis failed: " + "; ".join(details) }