import gradio as gr
from transformers import pipeline
import time
# ==========================================
# MODEL CONFIGURATION
# ==========================================
MODEL_NAME = "ENTUM-AI/roberta-clickbait-classifier"
print(f"Loading model: {MODEL_NAME}...")
try:
classifier = pipeline("text-classification", model=MODEL_NAME)
print("Model loaded successfully!")
except Exception as e:
print(f"Error loading model: {e}")
classifier = None
# ==========================================
# PREDICTION LOGIC
# ==========================================
def predict_single(text):
"""Classify a single headline."""
if not text or not text.strip():
return create_empty_result()
if classifier is None:
return create_error_result()
start = time.time()
result = classifier(text.strip())[0]
elapsed = (time.time() - start) * 1000
label = result["label"]
score = result["score"]
is_clickbait = label == "Clickbait"
return create_result_html(text.strip(), is_clickbait, score, elapsed)
def predict_batch(texts):
"""Classify multiple headlines (one per line)."""
if not texts or not texts.strip():
return "
Enter headlines, one per line.
"
if classifier is None:
return create_error_result()
lines = [line.strip() for line in texts.strip().split("\n") if line.strip()]
if not lines:
return "No valid headlines found.
"
start = time.time()
results = classifier(lines)
elapsed = (time.time() - start) * 1000
html_parts = []
clickbait_count = 0
for text, res in zip(lines, results):
is_clickbait = res["label"] == "Clickbait"
score = res["score"]
if is_clickbait:
clickbait_count += 1
color = "#dc2626" if is_clickbait else "#16a34a"
bg = "#fef2f2" if is_clickbait else "#f0fdf4"
icon = "đ¨" if is_clickbait else "â
"
label_text = "CLICKBAIT" if is_clickbait else "LEGIT"
bar_width = int(score * 100)
html_parts.append(f"""
{icon} {text}
{label_text} {score:.0%}
""")
summary_color = "#dc2626" if clickbait_count > len(lines) / 2 else "#16a34a"
summary_bg = "#fef2f2" if clickbait_count > len(lines) / 2 else "#f0fdf4"
summary = f"""
Batch Analysis
{clickbait_count} / {len(lines)} Clickbait
Processed in {elapsed:.0f}ms
"""
return summary + "\n".join(html_parts)
# ==========================================
# HTML RESULT BUILDERS
# ==========================================
def create_result_html(text, is_clickbait, score, elapsed_ms):
if is_clickbait:
main_color = "#dc2626"
gradient = "linear-gradient(135deg, #fee2e2, #fecaca, #fca5a5)"
icon = "đ¨"
label = "CLICKBAIT DETECTED"
subtitle = "This headline uses manipulative patterns to attract clicks."
text_color = "#991b1b"
else:
main_color = "#16a34a"
gradient = "linear-gradient(135deg, #dcfce7, #bbf7d0, #86efac)"
icon = "â
"
label = "LEGITIMATE NEWS"
subtitle = "This headline appears to be genuine and informative."
text_color = "#166534"
confidence_pct = int(score * 100)
return f"""
{icon}
{label}
{subtitle}
Analyzed Headline
"{text}"
Confidence
{confidence_pct}%
Latency
{elapsed_ms:.0f}ms
"""
def create_empty_result():
return """
đ
Awaiting Input
Enter a headline above and click Analyze
"""
def create_error_result():
return """
â ī¸
Model Not Available
Please wait while the model loads or try refreshing.
"""
# ==========================================
# CUSTOM CSS
# ==========================================
CUSTOM_CSS = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
* { font-family: 'Inter', 'Segoe UI', sans-serif !important; }
.gradio-container {
max-width: 960px !important;
margin: 0 auto !important;
background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 50%, #e2e8f0 100%) !important;
}
.main-header {
text-align: center;
padding: 40px 20px 20px;
}
.main-header h1 {
background: linear-gradient(135deg, #6366f1, #8b5cf6, #a855f7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 2.5rem !important;
font-weight: 800 !important;
margin-bottom: 8px !important;
letter-spacing: -0.5px;
}
.main-header p {
color: #64748b !important;
font-size: 15px !important;
}
.model-badge {
display: inline-block;
background: linear-gradient(135deg, #ede9fe, #e0e7ff);
border: 1px solid #c7d2fe;
color: #4f46e5 !important;
padding: 6px 16px;
border-radius: 24px;
font-size: 13px !important;
font-weight: 600;
letter-spacing: 0.5px;
margin-top: 12px;
}
footer { display: none !important; }
.tab-nav button {
color: #64748b !important;
font-weight: 600 !important;
font-size: 14px !important;
}
.tab-nav button.selected {
color: #6366f1 !important;
border-color: #6366f1 !important;
}
"""
# ==========================================
# GRADIO UI
# ==========================================
with gr.Blocks(
css=CUSTOM_CSS,
title="RoBERTa Clickbait Detector",
theme=gr.themes.Soft(
primary_hue="indigo",
secondary_hue="violet",
neutral_hue="slate",
),
) as demo:
# Header
gr.HTML("""
đ¯ Clickbait Detector
AI-powered headline analysis built on RoBERTa (125M parameters)
đ§ ENTUM-AI / roberta-clickbait-classifier
""")
with gr.Tabs():
# --- Tab 1: Single Analysis ---
with gr.Tab("đ Single Analysis"):
with gr.Row():
with gr.Column(scale=3):
single_input = gr.Textbox(
label="Headline",
placeholder="e.g. You Won't BELIEVE What This Celebrity Did Next!",
lines=2,
max_lines=3,
)
single_btn = gr.Button("⥠Analyze", variant="primary", size="lg")
with gr.Column(scale=4):
single_output = gr.HTML(value=create_empty_result())
gr.Examples(
examples=[
["You Won't BELIEVE What This Celebrity Did Next! đą"],
["Federal Reserve raises interest rates by 0.25 percentage points"],
["10 Shocking Secrets Your Doctor Doesn't Want You to Know"],
["Apple reports Q3 revenue of $81.4 billion, up 2% year over year"],
["This Simple Trick Will Make You a Millionaire Overnight!"],
["The European Central Bank holds interest rates unchanged at 4.5%"],
["SHOCKING: She walked into the room and what happened next changed everything"],
["NASA successfully launches Artemis II mission to lunar orbit"],
],
inputs=single_input,
label="đ Try these examples",
)
single_btn.click(fn=predict_single, inputs=single_input, outputs=single_output)
single_input.submit(fn=predict_single, inputs=single_input, outputs=single_output)
# --- Tab 2: Batch Analysis ---
with gr.Tab("đ Batch Analysis"):
gr.Markdown("Paste multiple headlines â **one per line** â for batch classification.")
with gr.Row():
with gr.Column(scale=2):
batch_input = gr.Textbox(
label="Headlines (one per line)",
placeholder="Headline 1\nHeadline 2\nHeadline 3",
lines=8,
max_lines=20,
)
batch_btn = gr.Button("⥠Analyze All", variant="primary", size="lg")
with gr.Column(scale=3):
batch_output = gr.HTML(
value="Results will appear here.
"
)
batch_btn.click(fn=predict_batch, inputs=batch_input, outputs=batch_output)
# --- Tab 3: About ---
with gr.Tab("âšī¸ About"):
gr.HTML("""
About This Model
| Architecture |
RoBERTa-base (125M parameters) |
| Task |
Binary Classification (Clickbait / Non-Clickbait) |
| Language |
English |
| Max Input |
128 tokens |
| License |
Apache 2.0 |
đ Training Data
Trained on ~48K samples from three combined & deduplicated English datasets:
christinacdl/Clickbait_New,
marksverdhei/clickbait_title_classification, and
contemmcm/clickbait.
đ Python API
from transformers import pipeline
classifier = pipeline("text-classification",
model="ENTUM-AI/roberta-clickbait-classifier")
result = classifier("You Won't BELIEVE What Happened!")
# [{'label': 'Clickbait', 'score': 0.99}]
đĄ Use Cases
đ°
News Aggregators
Filter low-quality clickbait articles
đ
Social Media
Content moderation & feed quality
đ
Browser Extensions
Warn users about misleading headlines
đ§
Email Filters
Detect clickbait-style subject lines
""")
# Launch
demo.launch()