import requests import json import base64 from io import BytesIO import time import os # Attempt to load .env automatically try: from dotenv import load_dotenv load_dotenv(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env')) except ImportError: # Manual fallback if python-dotenv is not installed env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env') if os.path.exists(env_path): with open(env_path, 'r') as f: for line in f: if line.strip() and not line.startswith('#'): key, val = line.strip().split('=', 1) os.environ[key.strip()] = val.strip() class ExternalAPIDetector: def __init__(self, api_endpoint=None, api_key=None, provider=None): """ Initializes the External API Detector. :param api_endpoint: The endpoint URL. :param api_key: The authentication key. :param provider: 'nvidia_nim' or 'huggingface' or 'mock' """ self.api_endpoint = api_endpoint self.api_key = api_key self.provider = provider # Check environment variables for NVIDIA NIM key env_nim_key = os.environ.get('NVIDIA_NIM_API_KEY') if env_nim_key and not self.api_key: self.api_key = env_nim_key self.provider = "nvidia_nim" if not self.api_endpoint: self.api_endpoint = "https://ai.api.nvidia.com/v1/cv/hive/deepfake-image-detection" # If no endpoint/key provided, default to mock if not self.api_endpoint or not self.api_key: self.provider = "mock" def analyze(self, image_pil): """ Sends the image to the external API for deepfake detection. :param image_pil: PIL Image. :return: dict with 'score' (0 to 1), 'confidence', and 'label'. """ if self.provider == "mock": return self._mock_analyze(image_pil) # Prepare image bytes buffered = BytesIO() image_pil.save(buffered, format="JPEG") img_bytes = buffered.getvalue() if self.provider == "huggingface": return self._analyze_huggingface(img_bytes) elif self.provider == "nvidia_nim": return self._analyze_nvidia_nim(img_bytes) else: raise ValueError(f"Unknown provider: {self.provider}") def _analyze_huggingface(self, img_bytes): headers = {"Authorization": f"Bearer {self.api_key}"} try: response = requests.post(self.api_endpoint, headers=headers, data=img_bytes) response.raise_for_status() result = response.json() # HuggingFace typically returns a list of dicts like: [{'label': 'fake', 'score': 0.9}, ...] fake_score = 0.0 real_score = 0.0 for item in result: label = item['label'].lower() if 'fake' in label or 'spoof' in label: fake_score += item['score'] elif 'real' in label or 'pristine' in label: real_score += item['score'] return { "score": float(fake_score), # Probability of being fake "confidence": 0.9, # External APIs are usually treated with high confidence "provider": self.provider } except Exception as e: print(f"HuggingFace API Error: {e}") return self._mock_analyze(None, error=str(e)) def _analyze_nvidia_nim(self, img_bytes): # Implementation for NVIDIA NIM API (build.nvidia.com) headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", "Accept": "application/json" } b64_img = base64.b64encode(img_bytes).decode('utf-8') payload = { "input": [f"data:image/jpeg;base64,{b64_img}"] } try: response = requests.post(self.api_endpoint, headers=headers, json=payload) response.raise_for_status() result = response.json() # Robust JSON parsing for NVIDIA NIM Hive Deepfake output fake_prob = 0.5 data_list = result.get('data', []) if data_list: # Hive usually returns classes array classes = data_list[0].get('classes', []) for cls in classes: if 'fake' in cls.get('name', '').lower() or 'deepfake' in cls.get('class', '').lower(): fake_prob = cls.get('score', 0.5) break return { "score": float(fake_prob), "confidence": 0.95, "provider": self.provider } except Exception as e: print(f"NVIDIA NIM API Error: {e}") return self._mock_analyze(None, error=str(e)) def _mock_analyze(self, image_pil, error=None): """ Mock implementation for testing when no API key is available. It simulates a network delay and returns a neutral score. """ # Simulate network latency time.sleep(0.5) return { "score": 0.5, # Neutral score "confidence": 0.1, # Low confidence because it's a mock "provider": "mock", "error": error } if __name__ == "__main__": detector = ExternalAPIDetector() from PIL import Image import numpy as np dummy_img = Image.fromarray(np.zeros((100, 100, 3), dtype=np.uint8)) print(detector.analyze(dummy_img))