BhavyaSoni21 commited on
Commit
30c1037
·
verified ·
1 Parent(s): 4cce576

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -35
app.py CHANGED
@@ -1,12 +1,13 @@
1
- from fastapi import FastAPI, HTTPException
2
- from pydantic import BaseModel
3
  import joblib
4
  import numpy as np
 
5
  from fastapi.middleware.cors import CORSMiddleware
 
6
 
7
  app = FastAPI(title="Bot Detection API")
8
 
9
- # Allow browser requests
10
  app.add_middleware(
11
  CORSMiddleware,
12
  allow_origins=["*"],
@@ -15,61 +16,63 @@ app.add_middleware(
15
  allow_headers=["*"],
16
  )
17
 
18
- # Expected number of features
19
- EXPECTED_FEATURES = 35
 
20
 
21
- # Request schema
22
  class InputData(BaseModel):
23
  features: list[float]
24
 
25
- # Load model
26
  try:
27
- model = joblib.load("bot_detection_model.pkl")
28
- except Exception as e:
29
- raise RuntimeError(f"Model failed to load: {e}")
 
 
30
 
31
- # Root endpoint
32
  @app.get("/")
33
- def home():
34
  return {
35
  "message": "Bot detection model running",
36
- "expected_features": EXPECTED_FEATURES
37
  }
38
 
39
- # Health check
40
  @app.get("/health")
41
- def health():
42
  return {"status": "ok"}
43
 
44
- # Prediction endpoint
45
- @app.post("/predict")
46
- def predict(data: InputData):
47
 
48
- # Validate feature count
 
49
  if len(data.features) != EXPECTED_FEATURES:
50
  raise HTTPException(
51
  status_code=400,
52
- detail=f"Expected {EXPECTED_FEATURES} features"
53
  )
54
 
55
  try:
56
- input_data = np.array(data.features).reshape(1, -1)
 
 
57
 
58
- prediction = model.predict(input_data)[0]
 
59
 
60
- # Convert prediction to readable output
61
- if prediction == 1:
62
- result = "bot_detected"
63
- else:
64
- result = "normal_traffic"
65
-
66
- return {
67
  "prediction": result,
68
- "raw_prediction": int(prediction)
69
  }
70
 
71
- except Exception as e:
72
- raise HTTPException(
73
- status_code=500,
74
- detail=f"Prediction failed: {str(e)}"
75
- )
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
  import joblib
4
  import numpy as np
5
+ from fastapi import FastAPI, HTTPException
6
  from fastapi.middleware.cors import CORSMiddleware
7
+ from pydantic import BaseModel
8
 
9
  app = FastAPI(title="Bot Detection API")
10
 
 
11
  app.add_middleware(
12
  CORSMiddleware,
13
  allow_origins=["*"],
 
16
  allow_headers=["*"],
17
  )
18
 
19
+ BASE_DIR = Path(__file__).resolve().parent
20
+ MODEL_PATH = BASE_DIR / "bot_detection_model.pkl"
21
+
22
 
 
23
  class InputData(BaseModel):
24
  features: list[float]
25
 
26
+
27
  try:
28
+ model = joblib.load(MODEL_PATH)
29
+ EXPECTED_FEATURES = int(getattr(model, "n_features_in_", 14))
30
+ except Exception as ex:
31
+ raise RuntimeError(f"Model failed to load: {ex}") from ex
32
+
33
 
 
34
  @app.get("/")
35
+ def home() -> dict[str, str | int]:
36
  return {
37
  "message": "Bot detection model running",
38
+ "expected_features": EXPECTED_FEATURES,
39
  }
40
 
41
+
42
  @app.get("/health")
43
+ def health() -> dict[str, str]:
44
  return {"status": "ok"}
45
 
 
 
 
46
 
47
+ @app.post("/predict")
48
+ def predict(data: InputData) -> dict[str, int | float | str]:
49
  if len(data.features) != EXPECTED_FEATURES:
50
  raise HTTPException(
51
  status_code=400,
52
+ detail=f"Expected {EXPECTED_FEATURES} features",
53
  )
54
 
55
  try:
56
+ x = np.asarray(data.features, dtype=np.float64).reshape(1, -1)
57
+ if not np.isfinite(x).all():
58
+ raise HTTPException(status_code=400, detail="Features contain NaN or Inf")
59
 
60
+ pred = int(model.predict(x)[0])
61
+ result = "bot_detected" if pred == 1 else "normal_traffic"
62
 
63
+ response: dict[str, int | float | str] = {
 
 
 
 
 
 
64
  "prediction": result,
65
+ "raw_prediction": pred,
66
  }
67
 
68
+ if hasattr(model, "predict_proba"):
69
+ proba = model.predict_proba(x)[0]
70
+ bot_idx = list(model.classes_).index(1)
71
+ response["bot_probability"] = float(proba[bot_idx])
72
+
73
+ return response
74
+ except HTTPException:
75
+ raise
76
+ except Exception as ex:
77
+ raise HTTPException(status_code=500, detail=f"Prediction failed: {ex}") from ex
78
+