fraudoo / fraud_analyzer.py
obaes's picture
Upload 10 files
71680bc verified
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