quantumbit's picture
🚀 Deploy via GitHub Actions
a70328e verified
Raw
History Blame Contribute Delete
2.62 kB
import joblib
import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
# ------------------------------------------------------------------
# App setup
# ------------------------------------------------------------------
app = FastAPI(
title="GitHub Spam Detector API",
description="Predicts whether a GitHub comment is spam (1) or not spam (0). "
"Trained on 100k+ real GitHub comments using TF-IDF + LinearSVC.",
version="1.0.0",
)
# ------------------------------------------------------------------
# Model loading (once at startup, never per-request)
# ------------------------------------------------------------------
MODEL_PATH = os.getenv("MODEL_PATH", "spam_detector_model_cv.pkl")
@app.on_event("startup")
def load_model():
global model
if not os.path.exists(MODEL_PATH):
raise RuntimeError(f"Model file not found at: {MODEL_PATH}")
model = joblib.load(MODEL_PATH)
print(f"Model loaded successfully from {MODEL_PATH}")
# ------------------------------------------------------------------
# Request / Response schemas
# ------------------------------------------------------------------
class PredictRequest(BaseModel):
text: str
class Config:
json_schema_extra = {
"example": {
"text": "Please fix the bug at line 56, it causes a null pointer exception."
}
}
class PredictResponse(BaseModel):
text: str
prediction: int # 0 = Not Spam, 1 = Spam
label: str # Human-readable label
# ------------------------------------------------------------------
# Endpoints
# ------------------------------------------------------------------
@app.get("/", tags=["Health"])
def root():
"""Health check endpoint."""
return {"status": "ok", "message": "Spam Detector API is running."}
@app.post("/predict", response_model=PredictResponse, tags=["Prediction"])
def predict(request: PredictRequest):
"""
Predict whether a piece of text is spam or not.
- **text**: The comment / text to classify.
Returns:
- **prediction**: `0` (Not Spam) or `1` (Spam)
- **label**: Human-readable string `"spam"` or `"not_spam"`
"""
if not request.text or not request.text.strip():
raise HTTPException(status_code=422, detail="Input text cannot be empty.")
raw_pred = model.predict([request.text])[0]
prediction = int(raw_pred)
label = "spam" if prediction == 1 else "not_spam"
return PredictResponse(
text=request.text,
prediction=prediction,
label=label,
)