Scam-Detector / main.py
Sanjam19's picture
Upload 12 files
cfe63e2 verified
Raw
History Blame Contribute Delete
10.2 kB
#main.py
from fastapi import FastAPI, HTTPException, Depends, status
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
import models
from database import engine, SessionLocal
from ml_utils import ScamDetectionService
from typing import Optional
import time
from datetime import datetime
# Create FastAPI app
app = FastAPI(
title="Multilingual Scam Detection API",
description="Simple API to detect scams in text messages and URLs",
version="1.0.0"
)
# Add CORS middleware
# app.add_middleware(
# CORSMiddleware,
# allow_origins=["*"], # Configure for production
# allow_credentials=True,
# allow_methods=["*"],
# allow_headers=["*"],
# )
# Create database tables
models.Base.metadata.create_all(bind=engine)
# Initialize scam detection service
scam_service = ScamDetectionService()
# Database dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# Pydantic models for requests/responses
class TextAnalysisRequest(BaseModel):
text: str = Field(min_length=1, max_length=5000)
language: Optional[str] = Field(default=None, description="Language code (en, es, fr)")
class URLAnalysisRequest(BaseModel):
url: str = Field(min_length=1)
context: Optional[str] = Field(default="", description="Additional context")
class ScamAnalysisResponse(BaseModel):
risk_level: str
confidence: float
reasoning: str
detected_language: Optional[str] = None
processing_time: float
timestamp: datetime
class URLAnalysisResponse(ScamAnalysisResponse):
url_status: str
domain: str
# Root endpoint
@app.get("/")
def root():
return {
"message": "Multilingual Scam Detection API",
"version": "1.0.0",
"endpoints": {
"analyze_text": "/analyze/text/",
"analyze_url": "/analyze/url/",
"health": "/health/",
"analytics": "/analytics/summary/"
}
}
# Health check
@app.get("/health/")
def health_check():
return {
"status": "healthy",
"timestamp": datetime.now(),
"database": "connected",
"ml_service": "active"
}
# Text analysis endpoint
@app.post("/analyze/text/", response_model=ScamAnalysisResponse)
def analyze_text(request: TextAnalysisRequest, db: Session = Depends(get_db)):
"""Analyze text message for scam indicators"""
start_time = time.time()
try:
# Detect language if not provided
detected_language = request.language or scam_service.detect_language(request.text)
# Analyze for scam
analysis = scam_service.analyze_text_scam(
text=request.text,
language=detected_language
)
processing_time = time.time() - start_time
# Save to database
scam_record = models.ScamAnalysis(
content=request.text,
content_type="text",
risk_level=analysis["risk_level"],
confidence=analysis["confidence"],
reasoning=analysis["reasoning"],
detected_language=detected_language,
processing_time=processing_time
)
db.add(scam_record)
db.commit()
return ScamAnalysisResponse(
risk_level=analysis["risk_level"],
confidence=analysis["confidence"],
reasoning=analysis["reasoning"],
detected_language=detected_language,
processing_time=round(processing_time, 3),
timestamp=datetime.now()
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Analysis failed: {str(e)}"
)
# URL analysis endpoint
@app.post("/analyze/url/", response_model=URLAnalysisResponse)
def analyze_url(request: URLAnalysisRequest, db: Session = Depends(get_db)):
"""Analyze URL for phishing/malicious behavior"""
start_time = time.time()
try:
# Analyze URL
analysis = scam_service.analyze_url_scam(
url=request.url,
context=request.context
)
processing_time = time.time() - start_time
# Save to database
scam_record = models.ScamAnalysis(
content=request.url,
content_type="url",
risk_level=analysis["risk_level"],
confidence=analysis["confidence"],
reasoning=analysis["reasoning"],
processing_time=processing_time,
additional_data={"domain": analysis["domain"], "url_status": analysis["url_status"]}
)
db.add(scam_record)
db.commit()
return URLAnalysisResponse(
risk_level=analysis["risk_level"],
confidence=analysis["confidence"],
reasoning=analysis["reasoning"],
url_status=analysis["url_status"],
domain=analysis["domain"],
processing_time=round(processing_time, 3),
timestamp=datetime.now()
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"URL analysis failed: {str(e)}"
)
# Language detection endpoint
@app.post("/detect/language/")
def detect_language(text: str):
"""Detect language of input text"""
try:
detected_lang = scam_service.detect_language(text)
confidence = scam_service.get_language_confidence(text)
return {
"text_preview": text[:100] + "..." if len(text) > 100 else text,
"detected_language": detected_lang,
"confidence": confidence,
"supported_languages": ["en", "es", "fr"]
}
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Language detection failed: {str(e)}"
)
# Basic analytics
@app.get("/analytics/summary/")
def get_analytics(db: Session = Depends(get_db)):
"""Get basic analytics summary"""
try:
total_analyses = db.query(models.ScamAnalysis).count()
# Count by risk level
safe_count = db.query(models.ScamAnalysis).filter(
models.ScamAnalysis.risk_level == "Safe"
).count()
suspicious_count = db.query(models.ScamAnalysis).filter(
models.ScamAnalysis.risk_level == "Suspicious"
).count()
scam_count = db.query(models.ScamAnalysis).filter(
models.ScamAnalysis.risk_level == "Scam"
).count()
# Count by content type
text_count = db.query(models.ScamAnalysis).filter(
models.ScamAnalysis.content_type == "text"
).count()
url_count = db.query(models.ScamAnalysis).filter(
models.ScamAnalysis.content_type == "url"
).count()
return {
"total_analyses": total_analyses,
"risk_distribution": {
"Safe": safe_count,
"Suspicious": suspicious_count,
"Scam": scam_count
},
"content_distribution": {
"text": text_count,
"url": url_count
},
"supported_languages": ["en", "es", "fr"]
}
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Analytics failed: {str(e)}"
)
# Recent analyses
@app.get("/history/recent/")
def get_recent_analyses(limit: int = 10, db: Session = Depends(get_db)):
"""Get recent scam analyses"""
try:
recent = db.query(models.ScamAnalysis).order_by(
models.ScamAnalysis.created_at.desc()
).limit(limit).all()
return {
"recent_analyses": [
{
"id": analysis.id,
"content_type": analysis.content_type,
"risk_level": analysis.risk_level,
"confidence": analysis.confidence,
"detected_language": analysis.detected_language,
"created_at": analysis.created_at,
"content_preview": (
analysis.content[:50] + "..."
if len(analysis.content) > 50
else analysis.content
)
}
for analysis in recent
],
"total_shown": len(recent)
}
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"History retrieval failed: {str(e)}"
)
# Test endpoint with sample data
@app.get("/test/samples/")
def test_samples():
"""Test with sample scam messages"""
samples = [
{
"text": "URGENT! Your bank account will be suspended. Click here: bit.ly/urgent-bank",
"expected_risk": "Scam"
},
{
"text": "Hello, how are you today? Hope you're doing well!",
"expected_risk": "Safe"
},
{
"text": "Congratulations! You've won $1000. Click to claim your prize now!",
"expected_risk": "Suspicious"
}
]
results = []
for sample in samples:
analysis = scam_service.analyze_text_scam(sample["text"])
results.append({
"text": sample["text"],
"expected": sample["expected_risk"],
"detected": analysis["risk_level"],
"confidence": analysis["confidence"],
"reasoning": analysis["reasoning"]
})
return {
"test_results": results,
"total_tests": len(results)
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)