import os from google import genai from PIL import Image import io import puremagic from pypdf import PdfReader import fitz # PyMuPDF from datetime import datetime class FraudAnalyzer: def __init__(self, api_key): self.client = genai.Client(api_key=api_key) # LLM Services 3 Flash for reasoning and extraction self.model_flash = 'gemini-3-flash-preview' # Nano Banana for specific image-centric analysis self.model_nano = 'nano-banana-pro-preview' def analyze_document(self, file_path): """Perform visual and structural analysis + data extraction.""" file_ext = os.path.splitext(file_path)[1].lower() metadata = self._extract_metadata(file_path) current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") visual_prompt = f"Today is {current_datetime}. Examine this image for visual manipulations: clones, font mismatches, edges around text, or retouching. Be extremely critical." extraction_prompt = f""" Today is {current_datetime}. Extract all text data from the following analysis and metadata. Return a structured analysis in JSON format with: - label: A short descriptive name for the document. - amount: Any monetary amount found (default 0 or null). - fraud_score: An integer score from 0 to 100 indicating fraud probability (0 = clean, 100 = definitely fraud). - detailed_analysis: Your full reasoning. - extracted_fields: Key names, dates, and ID numbers. """ image_input = None text_content = "" if file_ext in ['.png', '.jpg', '.jpeg']: image_input = Image.open(file_path) elif file_ext == '.pdf': # Extract text reader = PdfReader(file_path) for page in reader.pages: text_content += page.extract_text() # Convert first page to image for Nano Banana visual analysis try: doc = fitz.open(file_path) page = doc.load_page(0) pix = page.get_pixmap() img_data = pix.tobytes("png") image_input = Image.open(io.BytesIO(img_data)) doc.close() except Exception as e: print(f"Error converting PDF to image: {e}") if image_input: # Dual analysis for images (or PDF converted to image) visual_resp = self.client.models.generate_content( model=self.model_nano, contents=[visual_prompt, image_input] ) # Flash for Extraction & Combined Reasoning content_to_flash = [ extraction_prompt, f"Visual Analysis Report (from Nano Banana): {visual_resp.text}", f"Metadata: {metadata}" ] if text_content: # If PDF content_to_flash.append(f"Extracted Text: {text_content}") content_to_flash.append(image_input) combined_resp = self.client.models.generate_content( model=self.model_flash, contents=content_to_flash ) return { "llm_analysis": f"Visual Report (Nano Banana):\n{visual_resp.text}\n\nFinal Reasoning (Flash):\n{combined_resp.text}", "metadata": metadata } else: # Fallback for text-only or unsupported image conversion combined_resp = self.client.models.generate_content( model=self.model_flash, contents=[extraction_prompt, f"Metadata: {metadata}", f"Text: {text_content}"] ) return { "llm_analysis": f"Reasoning (Flash):\n{combined_resp.text}", "metadata": metadata } def _extract_metadata(self, file_path): """Extract file system and internal metadata.""" try: file_mime = puremagic.from_file(file_path, mime=True) except Exception: file_mime = "application/octet-stream" stats = os.stat(file_path) metadata = { "mime_type": file_mime, "size_bytes": stats.st_size, "modified_time": stats.st_mtime } if "image" in file_mime: try: img = Image.open(file_path) exif = img._getexif() if exif: metadata["exif"] = {str(k): str(v) for k, v in exif.items()} except Exception: pass return metadata