atharvawarade9807's picture
Update Version_3/main.py
67e55ca verified
Raw
History Blame Contribute Delete
4.87 kB
import math
import os
import sys
from pydantic import BaseModel, Field
# ── Import your existing cli.py functions directly ───────────────────────────
try:
from cli import clean_text, predict, load_models as cli_load_models
except ImportError:
# Fallback to handle relative imports if invoked directly by master gateway
from Version_3.cli import clean_text, predict, load_models as cli_load_models
# ─────────────────────────────────────────────────────────────────────────────
# 1. REQUIRED SCHEMAS FOR MASTER GATEWAY COMPATIBILITY
# ─────────────────────────────────────────────────────────────────────────────
class EmailScanRequest(BaseModel):
"""
Must use 'email_body' to match app.js and the validation expected by main.py
"""
email_body: str = Field(..., description="The raw email text or headers to scan")
class EmailScanResponse(BaseModel):
"""
Must match the exact structure enforced by response_model in master main.py
"""
verdict: str
confidence: float
# ─────────────────────────────────────────────────────────────────────────────
# 2. REQUIRED GLOBAL CONTEXT VARIABLES
# ─────────────────────────────────────────────────────────────────────────────
_vectorizer = None
_model = None
_load_error = None
def load_models():
"""
Called automatically by the master gateway bootstrapper.
"""
global _vectorizer, _model, _load_error
try:
_vectorizer, _model = cli_load_models()
print("[Chimera V3] SVM Models loaded successfully via master handshake.")
return _vectorizer, _model
except SystemExit:
_load_error = "Model files not found. Check models/SVM_model.pkl and models/vectorizer.pkl exist."
print(f"[Chimera V3] WARNING: {_load_error}")
except Exception as e:
_load_error = str(e)
print(f"[Chimera V3] WARNING: Could not load models — {_load_error}")
return None, None
# ─────────────────────────────────────────────────────────────────────────────
# 3. CORE ROUTING EXECUTION ENTRYPOINT
# ─────────────────────────────────────────────────────────────────────────────
def scan_email(payload: EmailScanRequest) -> EmailScanResponse:
"""
Direct functional endpoint executed by the master route handler.
"""
global _model, _vectorizer, _load_error
# Lazy loading safe-state fallback for mounted instances
if _model is None or _vectorizer is None:
_vectorizer, _model = load_models()
# If models are genuinely unavailable, fallback gracefully
if _model is None or _vectorizer is None:
return EmailScanResponse(
verdict="Suspicious (Model Offline)",
confidence=0.50
)
text_to_analyze = payload.email_body
# Guard: empty body text check
if not text_to_analyze.strip():
return EmailScanResponse(verdict="Clean", confidence=0.0)
# ── Run your underlying SVM model prediction ─────────────────────────────
# Emulating a blank display_name context to feed into your cli pipeline
combined_text = f"\n{text_to_analyze}"
label, confidence, spam_score = predict(combined_text, _vectorizer, _model)
# Calculate normalized confidence float (0.0 to 1.0)
risk_score = spam_score if spam_score is not None else (100.0 if label == "Spam" else 0.0)
final_confidence = (confidence / 100.0) if (confidence is not None) else (risk_score / 100.0)
# ── Map results to match standard frontend badge expectation ──────────────
if risk_score >= 70:
assigned_verdict = "phishing"
elif risk_score >= 40:
assigned_verdict = "suspicious"
else:
assigned_verdict = "clean"
return EmailScanResponse(
verdict=assigned_verdict,
confidence=final_confidence
)