Gamortsey commited on
Commit
7e66674
·
verified ·
1 Parent(s): c2d6849

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -10
app.py CHANGED
@@ -131,26 +131,24 @@ def predict_batch(texts: List[str], model_id: str = MODEL_ID_DEFAULT) -> List[Tu
131
  results.append((top_label, float(top_conf), probs))
132
  return results
133
 
134
- # ---------------- Explainability (simple occlusion) ----------------
135
- # (left intentionally minimal — UI only request)
136
 
137
  # ---------------- UI Callbacks ----------------
138
 
139
  # Single predict wrapper for Gradio
140
  def single_predict(text: str, model_id: str, threshold: float):
141
  txt = _prepare_text(text)
 
142
  if txt == "":
143
- return "", "0.0%", {}, "Empty input"
144
  try:
145
  probs, idx = predict_raw(txt, model_id)
146
  # sort probs descending
147
  probs_sorted = dict(sorted(probs.items(), key=lambda kv: kv[1], reverse=True))
148
  top_label = list(probs_sorted.keys())[0]
149
  top_conf = float(probs_sorted[top_label])
150
- # format as percentage for UI
151
  top_conf_pct = f"{top_conf * 100:.1f}%"
152
- # include percentage in the top prediction display as well
153
- top_label_display = f"{top_label} ({top_conf_pct})"
154
  warn = "" if top_conf >= threshold else f"Below threshold {threshold:.2f}"
155
 
156
  # log (no-op if history disabled)
@@ -165,9 +163,9 @@ def single_predict(text: str, model_id: str, threshold: float):
165
  except Exception:
166
  pass
167
 
168
- return top_label_display, top_conf_pct, probs_sorted, warn
169
  except Exception as e:
170
- return "", "0.0%", {}, f"Error: {str(e)}"
171
 
172
 
173
  # Batch predict from uploaded CSV (expects column 'message' or 'text')
@@ -216,6 +214,10 @@ MODERN_CSS = """
216
  .label-muted { color: #6b7280; font-size: 13px; }
217
  .small-note { font-size: 13px; color: #6b7280; }
218
  .warning-pill { background: #fff7ed; padding: 8px 12px; border-radius: 999px; display:inline-block; color: #92400e; font-weight:600; }
 
 
 
 
219
  """
220
 
221
 
@@ -223,7 +225,7 @@ def build_ui():
223
  with gr.Blocks(title="Phishing Detector", css=MODERN_CSS) as demo:
224
  with gr.Column():
225
  # Header
226
- gr.HTML("<div class='header-gradient'><h1 style='margin:0;'>🛡️ Phishing Detector</h1><p style='margin:6px 0 0 0; opacity:0.95;'>Classify messages or URLs as phishing or legitimate — clean, modern interface.</p></div>")
227
 
228
  with gr.Row(elem_id="main-row", variant="default"):
229
  # Left: Main actions
@@ -236,7 +238,7 @@ def build_ui():
236
  predict_btn = gr.Button("Analyze", variant="primary")
237
  with gr.Row():
238
  out_label = gr.Textbox(label="Top prediction", interactive=False)
239
- out_conf = gr.Textbox(label="Top confidence", interactive=False)
240
  out_probs = gr.JSON(label="Probabilities (descending)")
241
  warn_box = gr.Textbox(label="Warning", interactive=False)
242
 
 
131
  results.append((top_label, float(top_conf), probs))
132
  return results
133
 
134
+
 
135
 
136
  # ---------------- UI Callbacks ----------------
137
 
138
  # Single predict wrapper for Gradio
139
  def single_predict(text: str, model_id: str, threshold: float):
140
  txt = _prepare_text(text)
141
+ empty_bar = "<div class='conf-bar'><div class='conf-fill' style='width:0%'>0%</div></div>"
142
  if txt == "":
143
+ return "", empty_bar, {}, "Empty input"
144
  try:
145
  probs, idx = predict_raw(txt, model_id)
146
  # sort probs descending
147
  probs_sorted = dict(sorted(probs.items(), key=lambda kv: kv[1], reverse=True))
148
  top_label = list(probs_sorted.keys())[0]
149
  top_conf = float(probs_sorted[top_label])
 
150
  top_conf_pct = f"{top_conf * 100:.1f}%"
151
+ progress_html = f"<div class='conf-bar'><div class='conf-fill' style='width:{top_conf*100:.1f}%'>{top_conf_pct}</div></div>"
 
152
  warn = "" if top_conf >= threshold else f"Below threshold {threshold:.2f}"
153
 
154
  # log (no-op if history disabled)
 
163
  except Exception:
164
  pass
165
 
166
+ return top_label, progress_html, probs_sorted, warn
167
  except Exception as e:
168
+ return "", empty_bar, {}, f"Error: {str(e)}"
169
 
170
 
171
  # Batch predict from uploaded CSV (expects column 'message' or 'text')
 
214
  .label-muted { color: #6b7280; font-size: 13px; }
215
  .small-note { font-size: 13px; color: #6b7280; }
216
  .warning-pill { background: #fff7ed; padding: 8px 12px; border-radius: 999px; display:inline-block; color: #92400e; font-weight:600; }
217
+
218
+ /* confidence bar */
219
+ .conf-bar { background: #e6f0ff; border-radius: 999px; padding: 4px; width: 200px; }
220
+ .conf-fill { display:inline-block; height:26px; line-height:26px; padding:0 10px; border-radius: 999px; background: linear-gradient(90deg,#60a5fa,#3b82f6); color: white; font-weight:700; transition: width 400ms ease; }
221
  """
222
 
223
 
 
225
  with gr.Blocks(title="Phishing Detector", css=MODERN_CSS) as demo:
226
  with gr.Column():
227
  # Header
228
+ gr.HTML("<div class='header-gradient'><h1 style='margin:0;color:white;'>🛡️ Phishing Detector</h1><p style='margin:6px 0 0 0;color:rgba(255,255,255,0.95);'>Classify messages or URLs as phishing or legitimate — clean, modern interface.</p></div> ")
229
 
230
  with gr.Row(elem_id="main-row", variant="default"):
231
  # Left: Main actions
 
238
  predict_btn = gr.Button("Analyze", variant="primary")
239
  with gr.Row():
240
  out_label = gr.Textbox(label="Top prediction", interactive=False)
241
+ out_conf = gr.HTML("<div class='conf-bar'><div class='conf-fill' style='width:0%'>0%</div></div>", label="Confidence")
242
  out_probs = gr.JSON(label="Probabilities (descending)")
243
  warn_box = gr.Textbox(label="Warning", interactive=False)
244