SaiBon99 commited on
Commit
d0aa2ff
·
1 Parent(s): 739edba

Specify Python 3.12 for HF Space to match scikit-learn>=1.8.0 requirement

Browse files
Files changed (5) hide show
  1. HF_app/README.md +0 -0
  2. HF_app/app.py +0 -221
  3. HF_app/pyproject.toml +0 -16
  4. README.md +1 -0
  5. requirements.txt +4 -4
HF_app/README.md DELETED
Binary file (5.07 kB)
 
HF_app/app.py DELETED
@@ -1,221 +0,0 @@
1
- """
2
- Gradio app for phishing detection using URLScan.io and Hopsworks.
3
-
4
- This app:
5
- 1. Loads a trained model from Hopsworks Model Registry
6
- 2. Takes a URL as input
7
- 3. Scans it using URLScan.io API
8
- 4. Extracts features from the scan results
9
- 5. Runs inference using the loaded model
10
- 6. Returns whether the URL is likely phishing or legitimate
11
- """
12
-
13
- import os
14
- import logging
15
- import gradio as gr
16
- from typing import Tuple
17
-
18
- from phising_detection.inference import PhishingDetectionPipeline
19
-
20
- # Configure logging
21
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
22
- logger = logging.getLogger(__name__)
23
-
24
- # Global inference pipeline
25
- pipeline = None
26
-
27
-
28
- def initialize_app():
29
- """Initialize the app by loading the inference pipeline."""
30
- global pipeline
31
-
32
- try:
33
- # Get URLScan API key
34
- urlscan_api_key = os.getenv("URLSCAN_API_KEY")
35
-
36
- # Initialize pipeline
37
- pipeline = PhishingDetectionPipeline(
38
- model_name="phishing_detector",
39
- model_version=None, # Use latest version
40
- urlscan_api_key=urlscan_api_key
41
- )
42
-
43
- # Load model from Hopsworks
44
- pipeline.load_model_from_hopsworks()
45
- logger.info("Inference pipeline initialized successfully!")
46
-
47
- return True
48
- except Exception as e:
49
- logger.error(f"Failed to initialize app: {e}")
50
- return False
51
-
52
-
53
- def gradio_interface(url: str) -> Tuple[str, str, str]:
54
- """
55
- Gradio interface function.
56
-
57
- Args:
58
- url: URL to analyze
59
-
60
- Returns:
61
- Tuple of (result_html, confidence_html, details_html)
62
- """
63
- if not url or not url.strip():
64
- return "Please enter a URL", "", ""
65
-
66
- # Clean URL
67
- url = url.strip()
68
-
69
- # Add http:// if no protocol specified
70
- if not url.startswith(('http://', 'https://')):
71
- url = 'https://' + url
72
-
73
- # Run prediction using pipeline
74
- result = pipeline.predict_url(url)
75
-
76
- # Check for errors
77
- if "error" in result:
78
- return (
79
- f'<h2 style="color: orange;">ERROR</h2>',
80
- "",
81
- f"<p><strong>Error:</strong> {result['error']}</p>"
82
- )
83
-
84
- # Format result with color
85
- prediction = result["prediction"]
86
- confidence = result["confidence"]
87
-
88
- if prediction == "PHISHING":
89
- result_html = f'<h2 style="color: red;">PHISHING</h2>'
90
- color = "red"
91
- elif prediction == "LEGITIMATE":
92
- result_html = f'<h2 style="color: green;">LEGITIMATE</h2>'
93
- color = "green"
94
- else:
95
- result_html = f'<h2 style="color: orange;">UNKNOWN</h2>'
96
- color = "orange"
97
-
98
- confidence_html = f'<h3 style="color: {color};">Confidence: {confidence * 100:.2f}%</h3>'
99
-
100
- # Format details
101
- details_html = f"""
102
- <h4>Prediction Details:</h4>
103
- <ul>
104
- <li><strong>Phishing Probability:</strong> {result['phishing_probability'] * 100:.2f}%</li>
105
- <li><strong>Legitimate Probability:</strong> {result['legitimate_probability'] * 100:.2f}%</li>
106
- <li><strong>URLScan UUID:</strong> {result.get('scan_uuid', 'N/A')}</li>
107
- </ul>
108
-
109
- <h4>Extracted Features:</h4>
110
- <ul>
111
- <li><strong>Domain Age (days):</strong> {result['features'].get('domain_age_days', 'N/A')}</li>
112
- <li><strong>Secure Percentage:</strong> {result['features'].get('secure_percentage', 'N/A')}%</li>
113
- <li><strong>Has Umbrella Rank:</strong> {'Yes' if result['features'].get('has_umbrella_rank') else 'No'}</li>
114
- <li><strong>Umbrella Rank:</strong> {result['features'].get('umbrella_rank', 'N/A')}</li>
115
- <li><strong>Has TLS:</strong> {'Yes' if result['features'].get('has_tls') else 'No'}</li>
116
- <li><strong>TLS Valid Days:</strong> {result['features'].get('tls_valid_days', 'N/A')}</li>
117
- <li><strong>URL Length:</strong> {result['features'].get('url_length', 'N/A')}</li>
118
- <li><strong>Subdomain Count:</strong> {result['features'].get('subdomain_count', 'N/A')}</li>
119
- </ul>
120
- """
121
-
122
- return result_html, confidence_html, details_html
123
-
124
-
125
- def create_gradio_app():
126
- """Create and configure the Gradio interface."""
127
-
128
- # Custom CSS for better styling
129
- css = """
130
- .output-box {
131
- padding: 20px;
132
- border-radius: 10px;
133
- margin: 10px 0;
134
- }
135
- """
136
-
137
- with gr.Blocks(css=css, title="Phishing URL Detection") as demo:
138
- gr.Markdown(
139
- """
140
- # Phishing URL Detection
141
-
142
- Enter a URL to check if it's a phishing website or legitimate.
143
- This app uses URLScan.io to analyze the website and a machine learning model
144
- trained on URLScan features to predict if it's phishing.
145
-
146
- **Note:** Scanning a URL can take up to 90 seconds as we wait for URLScan.io to complete the analysis.
147
- """
148
- )
149
-
150
- with gr.Row():
151
- with gr.Column(scale=3):
152
- url_input = gr.Textbox(
153
- label="URL to Check",
154
- placeholder="Enter URL (e.g., example.com or https://example.com)",
155
- lines=1
156
- )
157
- with gr.Column(scale=1):
158
- submit_btn = gr.Button("Check URL", variant="primary", size="lg")
159
-
160
- with gr.Row():
161
- result_output = gr.HTML(label="Prediction")
162
-
163
- with gr.Row():
164
- confidence_output = gr.HTML(label="Confidence")
165
-
166
- with gr.Row():
167
- details_output = gr.HTML(label="Details")
168
-
169
- # Example URLs
170
- gr.Markdown("### Example URLs to Try:")
171
- gr.Examples(
172
- examples=[
173
- ["https://google.com"],
174
- ["https://github.com"],
175
- ["https://facebook.com"],
176
- ],
177
- inputs=url_input,
178
- )
179
-
180
- # Connect button to function
181
- submit_btn.click(
182
- fn=gradio_interface,
183
- inputs=url_input,
184
- outputs=[result_output, confidence_output, details_output]
185
- )
186
-
187
- gr.Markdown(
188
- """
189
- ---
190
- **Disclaimer:** This tool is for educational and research purposes only.
191
- The predictions are not 100% accurate and should not be the sole basis for security decisions.
192
- """
193
- )
194
-
195
- return demo
196
-
197
-
198
- def main():
199
- """Main function to run the Gradio app."""
200
- logger.info("Starting Phishing Detection App...")
201
-
202
- # Initialize app (load model and URLScan client)
203
- logger.info("Initializing app...")
204
- if not initialize_app():
205
- logger.error("Failed to initialize app. Exiting.")
206
- return
207
-
208
- # Create and launch Gradio app
209
- logger.info("Creating Gradio interface...")
210
- demo = create_gradio_app()
211
-
212
- logger.info("Launching Gradio app...")
213
- demo.launch(
214
- server_name="0.0.0.0",
215
- server_port=7860,
216
- share=False
217
- )
218
-
219
-
220
- if __name__ == "__main__":
221
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
HF_app/pyproject.toml DELETED
@@ -1,16 +0,0 @@
1
- [project]
2
- name = "hf-app"
3
- version = "0.1.0"
4
- description = "Hugging Face Gradio app for phishing detection using URLScan.io and Hopsworks"
5
- readme = "README.md"
6
- requires-python = ">=3.12, <3.14"
7
- dependencies = [
8
- "phising-detection",
9
- "gradio>=5.0.0",
10
- "hopsworks==4.2.*",
11
- "python-dotenv>=1.0.0",
12
- "joblib>=1.3.0",
13
- ]
14
-
15
- [tool.uv.sources]
16
- phising-detection = { workspace = true }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -7,6 +7,7 @@ sdk: gradio
7
  sdk_version: 5.0.0
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
  # Phishing URL Detection
 
7
  sdk_version: 5.0.0
8
  app_file: app.py
9
  pinned: false
10
+ python_version: 3.12
11
  ---
12
 
13
  # Phishing URL Detection
requirements.txt CHANGED
@@ -1,12 +1,12 @@
1
  # Dependencies for Hugging Face Space - Phishing Detection App
 
2
 
3
  # Core app framework
4
  gradio>=5.0.0
5
 
6
- # ML and Data
7
  scikit-learn>=1.8.0
8
  pandas>=2.1.0,<2.2.0
9
- numpy>=1.24.0
10
 
11
  # Hopsworks integration
12
  hopsworks==4.2.*
@@ -15,8 +15,8 @@ hopsworks==4.2.*
15
  requests>=2.32.5
16
  python-dotenv>=1.0.0
17
 
18
- # Model serialization
19
  joblib>=1.3.0
20
 
21
- # Additional dependencies
22
  pyarrow>=14.0.0
 
1
  # Dependencies for Hugging Face Space - Phishing Detection App
2
+ # Matches pyproject.toml but only includes inference dependencies
3
 
4
  # Core app framework
5
  gradio>=5.0.0
6
 
7
+ # ML and Data (matching pyproject.toml versions)
8
  scikit-learn>=1.8.0
9
  pandas>=2.1.0,<2.2.0
 
10
 
11
  # Hopsworks integration
12
  hopsworks==4.2.*
 
15
  requests>=2.32.5
16
  python-dotenv>=1.0.0
17
 
18
+ # Model serialization (included in scikit-learn but explicit for clarity)
19
  joblib>=1.3.0
20
 
21
+ # Additional dependencies (from pyproject.toml)
22
  pyarrow>=14.0.0