deveshpunjabi's picture
Upload folder using huggingface_hub
154408f verified
from fastapi import FastAPI, HTTPException, BackgroundTasks
from pydantic import BaseModel, HttpUrl
from typing import Optional, Dict, List, Any
import logging
import time
from src.core.pipeline import Pipeline
from src.ml import slm_explainer
# Configure Logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("api")
# Initialize App
app = FastAPI(
title="PhishingInsight API",
description="AI-powered Phishing Detection & URL Analysis API",
version="1.0.0"
)
# Initialize Pipeline (Global Singleton)
logger.info("API: Initializing Global Pipeline...")
pipeline = Pipeline()
# Load SLM in background on startup
@app.on_event("startup")
async def startup_event():
logger.info("API: Pre-loading SLM Model...")
# We do this asynchronously or threading to not block,
# but slm_explainer.load_model() blocking is safer for "ready" state.
# For now, we rely on the main process having loaded it previously
# or it loading on first request if isolated.
try:
slm_explainer.load_model()
logger.info("API: SLM Model Loaded.")
except Exception as e:
logger.error(f"API: Model load warning: {e}")
# --- Data Models ---
class URLRequest(BaseModel):
url: str
class SignalScores(BaseModel):
url_analysis: float
domain_check: float
class AnalysisResponse(BaseModel):
success: bool
url: str
verdict: str # SAFE, WARNING, DANGER
score: float # 0.0 to 1.0 (Risk)
is_phishing: bool
summary: str
explanation: str
advice: str
signals: SignalScores
findings: List[str]
timestamp: str
time_ms: int
error: Optional[str] = None
# --- Endpoints ---
@app.get("/health")
def health_check():
"""Health check endpoint for Docker/Kubernetes."""
return {"status": "healthy", "service": "PhishingInsight-API"}
@app.get("/version")
def version_info():
"""Return API and Model versions."""
return {
"api_version": "1.0.0",
"model_type": "Hybrid (LightGBM + TinyLlama)"
}
@app.post("/analyze", response_model=AnalysisResponse)
def analyze_url(request: URLRequest):
"""
Analyze a URL for phishing threats.
"""
logger.info(f"API Request: Analyze {request.url}")
result = pipeline.analyze(request.url)
if not result.get('success'):
logger.warning(f"API Analysis Failed: {result.get('error')}")
# Even if logical failure (invalid URL), we return a structured response with error
return {
"success": False,
"url": request.url,
"verdict": "ERROR",
"score": 0.0,
"is_phishing": False,
"summary": "Analysis Failed",
"explanation": result.get('error', "Unknown error"),
"advice": "Check the URL and try again.",
"signals": {"url_analysis": 0, "domain_check": 0},
"findings": [],
"timestamp": "",
"time_ms": 0,
"error": result.get('error')
}
return result