Model1 / app.py
BhavyaSoni21's picture
Update app.py
44c9031 verified
Raw
History Blame Contribute Delete
2.64 kB
from pathlib import Path
import joblib
import numpy as np
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
app = FastAPI(title="Web Attack Detection API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Assuming models are in the same directory as the script for deployment
# For Colab, you might need to adjust paths or upload files.
MODEL_PATH = "web_attack_detection_model.pkl"
VECTORIZER_PATH = "url_vectorizer.pkl"
class InputData(BaseModel):
features: list[float] # This assumes features are already numerical
# If you want to input URLs, you'd change this to:
# url: str
try:
model = joblib.load(MODEL_PATH)
vectorizer = joblib.load(VECTORIZER_PATH)
EXPECTED_FEATURES = len(vectorizer.get_feature_names_out())
except Exception as ex:
raise RuntimeError(f"Model or vectorizer failed to load: {ex}") from ex
@app.get("/")
def home() -> dict[str, str | int]:
return {
"message": "Web attack detection model running",
"expected_features": EXPECTED_FEATURES,
}
@app.get("/health")
def health() -> dict[str, str]:
return {"status": "ok"}
@app.post("/predict")
def predict(data: InputData) -> dict[str, int | float | str]:
# If InputData was 'url: str', you'd do:
# x = vectorizer.transform([data.url]).toarray()
if len(data.features) != EXPECTED_FEATURES:
raise HTTPException(
status_code=400,
detail=f"Expected {EXPECTED_FEATURES} features, but got {len(data.features)}",
)
try:
x = np.asarray(data.features, dtype=np.float64).reshape(1, -1)
if not np.isfinite(x).all():
raise HTTPException(status_code=400, detail="Features contain NaN or Inf")
pred = int(model.predict(x)[0])
# IsolationForest predicts -1 for anomalies (attacks), 1 for normal
result = "attack_detected" if pred == -1 else "normal_request"
response: dict[str, int | float | str] = {
"prediction": result,
"raw_prediction": pred,
}
# IsolationForest does not have predict_proba, use decision_function for anomaly score
# Lower scores typically mean more anomalous
anomaly_score = float(model.decision_function(x)[0])
response["anomaly_score"] = anomaly_score
return response
except HTTPException:
raise
except Exception as ex:
raise HTTPException(status_code=500, detail=f"Prediction failed: {ex}") from ex