Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -134,6 +134,80 @@ class GradioScamDetector:
|
|
| 134 |
|
| 135 |
return result_text, confidence, details, prob_chart
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
def create_probability_chart(self, trust_prob, scam_prob):
|
| 138 |
"""Create probability visualization"""
|
| 139 |
fig = go.Figure(data=[
|
|
@@ -215,8 +289,9 @@ class GradioScamDetector:
|
|
| 215 |
df = pd.DataFrame(self.prediction_history[-20:]) # Last 20 predictions
|
| 216 |
df['Confidence'] = df['confidence'].apply(lambda x: f"{x:.1%}")
|
| 217 |
df['Prediction'] = df['prediction'].apply(lambda x: f"🚫 {x.upper()}" if x == 'scam' else f"✅ {x.upper()}")
|
|
|
|
| 218 |
|
| 219 |
-
return df[['timestamp', 'message', 'Prediction', 'Confidence']].rename(columns={
|
| 220 |
'timestamp': 'Time',
|
| 221 |
'message': 'Message',
|
| 222 |
})
|
|
@@ -237,9 +312,13 @@ class GradioScamDetector:
|
|
| 237 |
"Suspicious": "URGENT: Your account will be suspended. Click link to verify now!"
|
| 238 |
}
|
| 239 |
|
|
|
|
|
|
|
|
|
|
| 240 |
def create_gradio_app():
|
| 241 |
"""Create and configure Gradio interface"""
|
| 242 |
|
|
|
|
| 243 |
# Initialize detector
|
| 244 |
detector = GradioScamDetector()
|
| 245 |
|
|
@@ -279,6 +358,64 @@ def create_gradio_app():
|
|
| 279 |
Simply enter a message below to check if it's legitimate or potentially fraudulent.
|
| 280 |
""")
|
| 281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
# Main prediction interface
|
| 283 |
with gr.Tab("🔍 Single Message Detection"):
|
| 284 |
with gr.Row():
|
|
@@ -381,6 +518,12 @@ def create_gradio_app():
|
|
| 381 |
- 📊 Confidence scoring
|
| 382 |
- 📁 Batch processing
|
| 383 |
- 📚 Prediction history
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
|
| 385 |
### Usage Tips
|
| 386 |
- Enter complete SMS messages for best results
|
|
|
|
| 134 |
|
| 135 |
return result_text, confidence, details, prob_chart
|
| 136 |
|
| 137 |
+
def predict_api(self, message):
|
| 138 |
+
"""API-friendly prediction function for webhooks"""
|
| 139 |
+
if not message or not message.strip():
|
| 140 |
+
return {
|
| 141 |
+
"status": "error",
|
| 142 |
+
"message": "Empty message",
|
| 143 |
+
"prediction": "unknown",
|
| 144 |
+
"confidence": 0.0
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
message = message.strip()
|
| 148 |
+
|
| 149 |
+
try:
|
| 150 |
+
# Tokenize message
|
| 151 |
+
encoding = self.tokenizer(
|
| 152 |
+
message,
|
| 153 |
+
truncation=True,
|
| 154 |
+
padding='max_length',
|
| 155 |
+
max_length=self.max_length,
|
| 156 |
+
return_tensors='pt'
|
| 157 |
+
)
|
| 158 |
+
|
| 159 |
+
input_ids = encoding['input_ids'].to(self.device)
|
| 160 |
+
attention_mask = encoding['attention_mask'].to(self.device)
|
| 161 |
+
|
| 162 |
+
with torch.no_grad():
|
| 163 |
+
outputs = self.model(input_ids, attention_mask)
|
| 164 |
+
probabilities = torch.nn.functional.softmax(outputs, dim=1)
|
| 165 |
+
_, prediction = torch.max(outputs, dim=1)
|
| 166 |
+
|
| 167 |
+
predicted_label = self.id2label[prediction.item()]
|
| 168 |
+
confidence = probabilities[0][prediction.item()].item()
|
| 169 |
+
trust_prob = probabilities[0][0].item()
|
| 170 |
+
scam_prob = probabilities[0][1].item()
|
| 171 |
+
|
| 172 |
+
# Format result
|
| 173 |
+
if predicted_label == 'scam':
|
| 174 |
+
result_text = "🚫 SCAM DETECTED"
|
| 175 |
+
alert_level = "HIGH"
|
| 176 |
+
else:
|
| 177 |
+
result_text = "✅ TRUSTED MESSAGE"
|
| 178 |
+
alert_level = "LOW"
|
| 179 |
+
|
| 180 |
+
# Store prediction history
|
| 181 |
+
self.prediction_history.append({
|
| 182 |
+
'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 183 |
+
'message': message[:50] + "..." if len(message) > 50 else message,
|
| 184 |
+
'prediction': predicted_label,
|
| 185 |
+
'confidence': confidence,
|
| 186 |
+
'trust_prob': trust_prob,
|
| 187 |
+
'scam_prob': scam_prob,
|
| 188 |
+
'source': 'API'
|
| 189 |
+
})
|
| 190 |
+
|
| 191 |
+
return {
|
| 192 |
+
"status": "success",
|
| 193 |
+
"message": message[:100] + "..." if len(message) > 100 else message,
|
| 194 |
+
"prediction": predicted_label,
|
| 195 |
+
"result_text": result_text,
|
| 196 |
+
"confidence": round(confidence, 4),
|
| 197 |
+
"trust_probability": round(trust_prob, 4),
|
| 198 |
+
"scam_probability": round(scam_prob, 4),
|
| 199 |
+
"alert_level": alert_level,
|
| 200 |
+
"timestamp": datetime.now().isoformat()
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
except Exception as e:
|
| 204 |
+
return {
|
| 205 |
+
"status": "error",
|
| 206 |
+
"message": f"Prediction failed: {str(e)}",
|
| 207 |
+
"prediction": "unknown",
|
| 208 |
+
"confidence": 0.0
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
def create_probability_chart(self, trust_prob, scam_prob):
|
| 212 |
"""Create probability visualization"""
|
| 213 |
fig = go.Figure(data=[
|
|
|
|
| 289 |
df = pd.DataFrame(self.prediction_history[-20:]) # Last 20 predictions
|
| 290 |
df['Confidence'] = df['confidence'].apply(lambda x: f"{x:.1%}")
|
| 291 |
df['Prediction'] = df['prediction'].apply(lambda x: f"🚫 {x.upper()}" if x == 'scam' else f"✅ {x.upper()}")
|
| 292 |
+
df['Source'] = df.get('source', 'Manual')
|
| 293 |
|
| 294 |
+
return df[['timestamp', 'message', 'Prediction', 'Confidence', 'Source']].rename(columns={
|
| 295 |
'timestamp': 'Time',
|
| 296 |
'message': 'Message',
|
| 297 |
})
|
|
|
|
| 312 |
"Suspicious": "URGENT: Your account will be suspended. Click link to verify now!"
|
| 313 |
}
|
| 314 |
|
| 315 |
+
# Global detector instance for API endpoints
|
| 316 |
+
detector = None
|
| 317 |
+
|
| 318 |
def create_gradio_app():
|
| 319 |
"""Create and configure Gradio interface"""
|
| 320 |
|
| 321 |
+
global detector
|
| 322 |
# Initialize detector
|
| 323 |
detector = GradioScamDetector()
|
| 324 |
|
|
|
|
| 358 |
Simply enter a message below to check if it's legitimate or potentially fraudulent.
|
| 359 |
""")
|
| 360 |
|
| 361 |
+
# API Information Tab
|
| 362 |
+
with gr.Tab("🔌 API Integration"):
|
| 363 |
+
gr.Markdown("""
|
| 364 |
+
## 📡 API Endpoints for IFTTT/Zapier Integration
|
| 365 |
+
|
| 366 |
+
### For IFTTT Webhook:
|
| 367 |
+
```
|
| 368 |
+
URL: https://jacksonwambali-bert.hf.space/api/predict
|
| 369 |
+
Method: POST
|
| 370 |
+
Content-Type: application/json
|
| 371 |
+
Body: {"data": ["Your SMS message here"]}
|
| 372 |
+
```
|
| 373 |
+
|
| 374 |
+
### For Zapier Webhook:
|
| 375 |
+
```
|
| 376 |
+
URL: https://jacksonwambali-bert.hf.space/api/predict
|
| 377 |
+
Method: POST
|
| 378 |
+
Content-Type: application/json
|
| 379 |
+
Payload: {"data": ["{{sms_text}}"]}
|
| 380 |
+
```
|
| 381 |
+
|
| 382 |
+
### Response Format:
|
| 383 |
+
```json
|
| 384 |
+
{
|
| 385 |
+
"data": [
|
| 386 |
+
{
|
| 387 |
+
"status": "success",
|
| 388 |
+
"prediction": "scam" or "trust",
|
| 389 |
+
"result_text": "🚫 SCAM DETECTED" or "✅ TRUSTED MESSAGE",
|
| 390 |
+
"confidence": 0.95,
|
| 391 |
+
"alert_level": "HIGH" or "LOW"
|
| 392 |
+
}
|
| 393 |
+
]
|
| 394 |
+
}
|
| 395 |
+
```
|
| 396 |
+
|
| 397 |
+
### Quick Test:
|
| 398 |
+
Use the form below to test your API integration:
|
| 399 |
+
""")
|
| 400 |
+
|
| 401 |
+
with gr.Row():
|
| 402 |
+
with gr.Column():
|
| 403 |
+
api_test_input = gr.Textbox(
|
| 404 |
+
label="📱 Test SMS Message",
|
| 405 |
+
placeholder="Enter SMS to test API response...",
|
| 406 |
+
lines=3
|
| 407 |
+
)
|
| 408 |
+
api_test_btn = gr.Button("🧪 Test API Response", variant="primary")
|
| 409 |
+
|
| 410 |
+
with gr.Column():
|
| 411 |
+
api_response = gr.JSON(label="📊 API Response")
|
| 412 |
+
|
| 413 |
+
api_test_btn.click(
|
| 414 |
+
fn=lambda msg: detector.predict_api(msg) if detector else {"error": "Model not loaded"},
|
| 415 |
+
inputs=api_test_input,
|
| 416 |
+
outputs=api_response
|
| 417 |
+
)
|
| 418 |
+
|
| 419 |
# Main prediction interface
|
| 420 |
with gr.Tab("🔍 Single Message Detection"):
|
| 421 |
with gr.Row():
|
|
|
|
| 518 |
- 📊 Confidence scoring
|
| 519 |
- 📁 Batch processing
|
| 520 |
- 📚 Prediction history
|
| 521 |
+
- 🔌 API integration for IFTTT/Zapier
|
| 522 |
+
|
| 523 |
+
### SMS Integration
|
| 524 |
+
- Connect with IFTTT for automatic SMS scanning
|
| 525 |
+
- Webhook support for real-time alerts
|
| 526 |
+
- Batch processing for multiple messages
|
| 527 |
|
| 528 |
### Usage Tips
|
| 529 |
- Enter complete SMS messages for best results
|