Spaces:
Sleeping
Sleeping
Update app_gradio.py
Browse files- app_gradio.py +58 -74
app_gradio.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
"""
|
| 2 |
Log Classification System β HuggingFace Spaces
|
| 3 |
-
Optimized for
|
| 4 |
"""
|
| 5 |
from __future__ import annotations
|
| 6 |
import io
|
|
@@ -11,7 +11,7 @@ import gradio as gr
|
|
| 11 |
from classify import classify_log, classify_csv
|
| 12 |
from processor_bert import preload_models
|
| 13 |
|
| 14 |
-
# ββ Preload models
|
| 15 |
preload_models()
|
| 16 |
|
| 17 |
SOURCES = [
|
|
@@ -34,20 +34,24 @@ EXAMPLE_LOGS = [
|
|
| 34 |
["LegacyCRM", "Case escalation for ticket ID 7324 failed β support agent is no longer active."],
|
| 35 |
]
|
| 36 |
|
| 37 |
-
# ββ CSS
|
| 38 |
CUSTOM_CSS = """
|
| 39 |
-
@import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@600&family=Share+Tech+Mono&family=Exo+2:wght@400;600&display=swap');
|
| 40 |
:root {
|
| 41 |
--bg-primary: #050810;
|
| 42 |
--accent-cyan: #00d4ff;
|
| 43 |
--text-primary: #e2e8f0;
|
| 44 |
}
|
| 45 |
body, .gradio-container { background: var(--bg-primary) !important; font-family: 'Exo 2', sans-serif !important; }
|
| 46 |
-
.gradio-group {
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
font-weight: bold !important;
|
| 52 |
}
|
| 53 |
"""
|
|
@@ -55,116 +59,96 @@ button.primary {
|
|
| 55 |
# ββ Functions βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 56 |
|
| 57 |
def classify_single(source: str, log_message: str):
|
| 58 |
-
# Dynamic import to check model status
|
| 59 |
from processor_bert import _model_ready
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
return "Empty Input", "β", "β", "0 ms"
|
| 63 |
-
|
| 64 |
if not _model_ready:
|
| 65 |
-
return "β³ Models Loading...", "Please wait
|
| 66 |
|
|
|
|
| 67 |
try:
|
| 68 |
-
t0 = time.perf_counter()
|
| 69 |
result = classify_log(source, log_message)
|
| 70 |
latency = (time.perf_counter() - t0) * 1000
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
except Exception as e:
|
| 79 |
-
return f"Error: {str(e)}", "
|
| 80 |
|
| 81 |
def classify_batch(file, progress=gr.Progress(track_tqdm=True)):
|
| 82 |
-
if file is None:
|
| 83 |
-
return None, "β οΈ Please upload a CSV file."
|
| 84 |
|
| 85 |
-
progress(0, desc="Starting
|
| 86 |
t0 = time.perf_counter()
|
| 87 |
|
| 88 |
try:
|
| 89 |
-
# Note: If classify_csv is slow, we wrap it in progress feedback
|
| 90 |
output_path, df = classify_csv(file.name, "/tmp/classified_output.csv")
|
|
|
|
| 91 |
|
| 92 |
-
progress(0.8, desc="Generating Statistics...")
|
| 93 |
total = len(df)
|
| 94 |
tier_counts = df["tier_used"].value_counts().to_dict()
|
| 95 |
-
label_counts = df["predicted_label"].value_counts().to_dict()
|
| 96 |
-
|
| 97 |
-
# Stats Formatting
|
| 98 |
tier_info = "\n".join([f" {TIER_COLORS.get(k,'βͺ')} {k}: {v}" for k,v in tier_counts.items()])
|
| 99 |
-
label_info = "\n".join([f" β’ {k}: {v}" for k,v in label_counts.items()])
|
| 100 |
|
| 101 |
-
total_time = time.perf_counter() - t0
|
| 102 |
stats = (
|
| 103 |
f"β
PROCESSED {total} LOGS\n"
|
| 104 |
-
f"β±οΈ TOTAL TIME: {
|
| 105 |
-
f"π TIER
|
| 106 |
-
f"π·οΈ LABEL DISTRIBUTION:\n{label_info}"
|
| 107 |
)
|
| 108 |
-
|
| 109 |
-
progress(1.0, desc="Done!")
|
| 110 |
return output_path, stats
|
| 111 |
-
|
| 112 |
except Exception as e:
|
| 113 |
-
return None, f"β
|
| 114 |
-
|
| 115 |
-
# ββ UI Construction ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 116 |
|
|
|
|
| 117 |
THEME = gr.themes.Base(
|
| 118 |
primary_hue="blue",
|
|
|
|
| 119 |
neutral_hue="slate",
|
| 120 |
font=[gr.themes.GoogleFont("Exo 2")],
|
| 121 |
-
).set(
|
| 122 |
-
block_background_fill="#0d1425",
|
| 123 |
-
block_label_text_color="#00d4ff",
|
| 124 |
-
input_background_fill="#050810",
|
| 125 |
)
|
| 126 |
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
|
|
|
| 130 |
with gr.Tabs():
|
| 131 |
-
|
| 132 |
-
with gr.Tab("β‘ REAL-TIME ANALYZER"):
|
| 133 |
with gr.Row():
|
| 134 |
with gr.Column(scale=1):
|
| 135 |
-
|
| 136 |
with gr.Column(scale=3):
|
| 137 |
-
|
| 138 |
|
| 139 |
-
run_btn = gr.Button("
|
| 140 |
|
| 141 |
with gr.Row():
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
run_btn.click(classify_single, [src, msg], [out_lbl, out_tier, out_conf, out_lat])
|
| 148 |
-
gr.Examples(examples=EXAMPLE_LOGS, inputs=[src, msg])
|
| 149 |
|
| 150 |
-
|
| 151 |
-
|
|
|
|
|
|
|
| 152 |
with gr.Row():
|
| 153 |
with gr.Column():
|
| 154 |
-
|
| 155 |
-
batch_btn = gr.Button("
|
| 156 |
with gr.Column():
|
| 157 |
-
|
| 158 |
-
stats_out = gr.Textbox(label="
|
| 159 |
|
| 160 |
-
batch_btn.click(classify_batch, inputs=[
|
| 161 |
-
|
| 162 |
-
gr.Markdown("--- \n *System Status: Active | Tiers: Regex -> BERT -> LLM*")
|
| 163 |
|
| 164 |
-
# ββ Launch
|
| 165 |
-
#
|
| 166 |
demo.queue(default_concurrency_limit=2).launch(
|
| 167 |
server_name="0.0.0.0",
|
| 168 |
server_port=7860,
|
| 169 |
-
|
|
|
|
| 170 |
)
|
|
|
|
| 1 |
"""
|
| 2 |
Log Classification System β HuggingFace Spaces
|
| 3 |
+
Optimized for Gradio 6.0 & HF Free Tier (2 vCPU / 16GB RAM)
|
| 4 |
"""
|
| 5 |
from __future__ import annotations
|
| 6 |
import io
|
|
|
|
| 11 |
from classify import classify_log, classify_csv
|
| 12 |
from processor_bert import preload_models
|
| 13 |
|
| 14 |
+
# ββ Preload models (Important for BERT speed) βββββββββββββββββ
|
| 15 |
preload_models()
|
| 16 |
|
| 17 |
SOURCES = [
|
|
|
|
| 34 |
["LegacyCRM", "Case escalation for ticket ID 7324 failed β support agent is no longer active."],
|
| 35 |
]
|
| 36 |
|
| 37 |
+
# ββ Custom CSS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 38 |
CUSTOM_CSS = """
|
| 39 |
+
@import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@400;600;700&family=Share+Tech+Mono&family=Exo+2:wght@300;400;600&display=swap');
|
| 40 |
:root {
|
| 41 |
--bg-primary: #050810;
|
| 42 |
--accent-cyan: #00d4ff;
|
| 43 |
--text-primary: #e2e8f0;
|
| 44 |
}
|
| 45 |
body, .gradio-container { background: var(--bg-primary) !important; font-family: 'Exo 2', sans-serif !important; }
|
| 46 |
+
.gradio-group {
|
| 47 |
+
background: #0d1425 !important;
|
| 48 |
+
border: 1px solid rgba(0, 212, 255, 0.1) !important;
|
| 49 |
+
border-radius: 20px !important;
|
| 50 |
+
}
|
| 51 |
+
button.primary {
|
| 52 |
+
background: linear-gradient(135deg, #0066ff, #00d4ff) !important;
|
| 53 |
+
border: none !important;
|
| 54 |
+
color: white !important;
|
| 55 |
font-weight: bold !important;
|
| 56 |
}
|
| 57 |
"""
|
|
|
|
| 59 |
# ββ Functions βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 60 |
|
| 61 |
def classify_single(source: str, log_message: str):
|
|
|
|
| 62 |
from processor_bert import _model_ready
|
| 63 |
+
if not log_message.strip():
|
| 64 |
+
return "β", "β", "β", "β"
|
|
|
|
|
|
|
| 65 |
if not _model_ready:
|
| 66 |
+
return "β³ Models Loading...", "Please wait", "β", "β"
|
| 67 |
|
| 68 |
+
t0 = time.perf_counter()
|
| 69 |
try:
|
|
|
|
| 70 |
result = classify_log(source, log_message)
|
| 71 |
latency = (time.perf_counter() - t0) * 1000
|
| 72 |
+
icon = TIER_COLORS.get(result["tier"], "βͺ")
|
| 73 |
+
return (
|
| 74 |
+
result["label"],
|
| 75 |
+
f"{icon} {result['tier']}",
|
| 76 |
+
f"{result['confidence']:.1%}" if result["confidence"] else "N/A",
|
| 77 |
+
f"{latency:.1f} ms"
|
| 78 |
+
)
|
| 79 |
except Exception as e:
|
| 80 |
+
return f"Error: {str(e)}", "Fail", "β", "β"
|
| 81 |
|
| 82 |
def classify_batch(file, progress=gr.Progress(track_tqdm=True)):
|
| 83 |
+
if file is None: return None, "β οΈ No file uploaded."
|
|
|
|
| 84 |
|
| 85 |
+
progress(0, desc="π Starting Batch Process...")
|
| 86 |
t0 = time.perf_counter()
|
| 87 |
|
| 88 |
try:
|
|
|
|
| 89 |
output_path, df = classify_csv(file.name, "/tmp/classified_output.csv")
|
| 90 |
+
progress(0.8, desc="π Generating Stats...")
|
| 91 |
|
|
|
|
| 92 |
total = len(df)
|
| 93 |
tier_counts = df["tier_used"].value_counts().to_dict()
|
|
|
|
|
|
|
|
|
|
| 94 |
tier_info = "\n".join([f" {TIER_COLORS.get(k,'βͺ')} {k}: {v}" for k,v in tier_counts.items()])
|
|
|
|
| 95 |
|
|
|
|
| 96 |
stats = (
|
| 97 |
f"β
PROCESSED {total} LOGS\n"
|
| 98 |
+
f"β±οΈ TOTAL TIME: {time.perf_counter() - t0:.2f}s\n\n"
|
| 99 |
+
f"π TIER USAGE:\n{tier_info}"
|
|
|
|
| 100 |
)
|
|
|
|
|
|
|
| 101 |
return output_path, stats
|
|
|
|
| 102 |
except Exception as e:
|
| 103 |
+
return None, f"β Error: {str(e)}"
|
|
|
|
|
|
|
| 104 |
|
| 105 |
+
# ββ Theme Configuration βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 106 |
THEME = gr.themes.Base(
|
| 107 |
primary_hue="blue",
|
| 108 |
+
secondary_hue="cyan",
|
| 109 |
neutral_hue="slate",
|
| 110 |
font=[gr.themes.GoogleFont("Exo 2")],
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
)
|
| 112 |
|
| 113 |
+
# ββ UI Layout βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 114 |
+
with gr.Blocks(title="Log AI Engine") as demo:
|
| 115 |
+
gr.HTML("<div style='text-align: center; padding: 20px;'><h1>π LOG CLASSIFICATION SYSTEM</h1></div>")
|
| 116 |
+
|
| 117 |
with gr.Tabs():
|
| 118 |
+
with gr.Tab("β‘ SINGLE ANALYZER"):
|
|
|
|
| 119 |
with gr.Row():
|
| 120 |
with gr.Column(scale=1):
|
| 121 |
+
src_in = gr.Dropdown(choices=SOURCES, value="ModernCRM", label="SOURCE")
|
| 122 |
with gr.Column(scale=3):
|
| 123 |
+
msg_in = gr.Textbox(label="LOG MESSAGE", placeholder="Paste log line...", lines=3)
|
| 124 |
|
| 125 |
+
run_btn = gr.Button("βΆ CLASSIFY", variant="primary")
|
| 126 |
|
| 127 |
with gr.Row():
|
| 128 |
+
lbl_out = gr.Textbox(label="LABEL")
|
| 129 |
+
tier_out = gr.Textbox(label="TIER")
|
| 130 |
+
conf_out = gr.Textbox(label="CONFIDENCE")
|
| 131 |
+
lat_out = gr.Textbox(label="LATENCY")
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
+
run_btn.click(classify_single, [src_in, msg_in], [lbl_out, tier_out, conf_out, lat_out])
|
| 134 |
+
gr.Examples(examples=EXAMPLE_LOGS, inputs=[src_in, msg_in])
|
| 135 |
+
|
| 136 |
+
with gr.Tab("π¦ BATCH CSV"):
|
| 137 |
with gr.Row():
|
| 138 |
with gr.Column():
|
| 139 |
+
csv_in = gr.File(label="UPLOAD CSV", file_types=[".csv"])
|
| 140 |
+
batch_btn = gr.Button("βΆ PROCESS ALL", variant="primary")
|
| 141 |
with gr.Column():
|
| 142 |
+
csv_out = gr.File(label="DOWNLOAD RESULTS")
|
| 143 |
+
stats_out = gr.Textbox(label="SUMMARY", lines=10)
|
| 144 |
|
| 145 |
+
batch_btn.click(classify_batch, inputs=[csv_in], outputs=[csv_out, stats_out])
|
|
|
|
|
|
|
| 146 |
|
| 147 |
+
# ββ Optimized Launch ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 148 |
+
# Gradio 6.0 mein theme aur css launch() ke andar honge
|
| 149 |
demo.queue(default_concurrency_limit=2).launch(
|
| 150 |
server_name="0.0.0.0",
|
| 151 |
server_port=7860,
|
| 152 |
+
theme=THEME,
|
| 153 |
+
css=CUSTOM_CSS
|
| 154 |
)
|