File size: 3,791 Bytes
7500cab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | """
Creating a REST API for predicting phishing probability of URLs.
Exposes POST /predict endpoint:
- Accepts JSON: {"url": "<URL>"}
- Returns JSON: {"phishing": <probability>}
Features:
- Interactive API docs available at /docs (Swagger UI) and /redoc (ReDoc)
- Automatic input validation
- Returns 400 if "url" is missing or invalid
- Returns 500 for unexpected errors
Usage:
1. Run the server:
uvicorn app:app --reload
2. Open browser to http://127.0.0.1:8000/docs to test endpoints interactively
"""
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parent.parent))
import torch
from flask import Flask, request, jsonify
from data.tokenizer import url_to_ids
app = Flask(__name__)
# Loading TorchScript Model and setting it to evaluation
model = torch.jit.load("./models/phish_model_ts.pt")
model.eval()
@app.route("/", methods=["GET"])
def home():
return """
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PhishGuard API</title>
<style>
body {
font-family: system-ui;
background: #f6f8fa;
margin: 2rem;
line-height: 1.6;
}
h1 { color: #d32f2f; }
pre {
background: #ebebeb;
padding: 1rem;
overflow-x: auto;
border-radius: 6px;
white-space: pre-wrap;
}
code {
background: #ebebeb;
padding: 2px 4px;
border-radius: 4px;
}
.step { margin: 1.2rem 0; }
</style>
<h1>PhishGuard API</h1>
<p>
This server predicts how <em>phishy</em> a URL is.<br>
Send a POST request to <code>/predict</code> with JSON:
</p>
<pre>{"url": "https://example.com"}</pre>
<p><i>Tip: Replace <code>https://example.com</code> with any URL you want to check.</i></p>
<h2>βΆ Test in CMD / Terminal (5 seconds)</h2>
<div class="step">
<b>Copy β paste β Enter:</b>
<pre>
curl -X POST http://127.0.0.1:8000/predict \
-H "Content-Type: application/json" \
-d "{\"url\": \"https://example.com\"}"
</pre>
<p><i>Replace the URL with the one you want to test.</i></p>
</div>
<h2>β‘ GUI inside VS Code</h2>
<div class="step">
<b>Using Thunder Client (free):</b><br>
1. Install "Thunder Client" from Extensions.<br>
2. New Request β POST<br>
3. URL: <code>http://127.0.0.1:8000/predict</code><br>
4. Body β Raw β JSON<br>
5. Paste:<br>
<code>{"url": "https://example.com"}</code><br>
6. Send.
</div>
<h2>β’ Postman (any OS)</h2>
<div class="step">
1. New Request β POST<br>
2. URL: <code>http://127.0.0.1:8000/predict</code><br>
3. Body β Raw β JSON<br>
4. Paste payload β Send.
</div>
<h2>What the number means</h2>
<ul>
<li>0.0 β 0.5 β likely <strong>safe</strong></li>
<li>0.5 β 1.0 β likely <strong>phishing</strong></li>
</ul>
<p>That's it β happy testing!</p>
</html>
""", 200
@app.route("/predict", methods = ["POST"])
def predict():
"""Processing POST requests and returning phishing score"""
try:
# Getting URL from request JSON safely
data = request.get_json(force = True)
url = data.get("url")
# Converting URL to token IDs
ids = torch.tensor([url_to_ids(url)], dtype= torch.long)
# Running model inference without gradients
with torch.no_grad():
score = float(model(ids)[0])
# Returning phishing probability as JSON
return jsonify({"phishing" : score})
except Exception as e:
return jsonify({"error" : str(e)}), 500
if __name__ == "__main__":
# Running flask server on port 5000
# print(url_to_ids("http://secure-login-paypal.com.verify-account-update.co/login"))
app.run(port=5000, debug = False) |