from pathlib import Path import os import gradio as gr from emotion_classifier import DEFAULT_MODEL_DIR, EmotionClassifier classifier = EmotionClassifier() THEME = gr.themes.Soft( primary_hue="teal", secondary_hue="rose", neutral_hue="zinc", radius_size="sm", ) CSS = """ .emotion-shell { max-width: 980px; margin: 0 auto; } .status-box { border-left: 4px solid #0f766e; padding: 12px 14px; background: #f8fafc; } .missing-box { border-left: 4px solid #be123c; padding: 12px 14px; background: #fff1f2; } .emotion-card { border: 1px solid #d4d4d8; padding: 16px; background: white; } .emotion-value { font-size: 28px; font-weight: 700; color: #0f766e; } """ def model_status() -> str: model_dir = Path(os.getenv("EMOTION_MODEL_DIR", DEFAULT_MODEL_DIR)) if model_dir.exists(): return "
Local trained emotion model is ready.
" return ( "
Local emotion model is not available yet. " "Add the trained saved_emotion_model folder before testing.
" ) def _empty_result(message: str) -> tuple[str, list[list[str | float]], str]: return ( f"
{message}
", [], model_status(), ) def predict_emotion(text: str) -> tuple[str, list[list[str | float]], str]: if not (text or "").strip(): return _empty_result("Please enter a message to analyze.") try: result = classifier.explain(text or "", top_k=8) emotion = result["prediction"]["emotion"] confidence = result["prediction"]["confidence"] card = ( "
" "
Predicted emotion
" f"
{emotion.title()}
" f"
Confidence: {confidence:.1%}
" "
" ) evidence = [ [ item["word"], item["impact"], item["confidence_without_word"], item["effect"], ] for item in result["all_evidence"] ] status = "
Prediction generated by the local trained DistilBERT model.
" return card, evidence, status except FileNotFoundError: return _empty_result("Local emotion model is not available yet.") except ImportError as exc: return _empty_result(f"Missing dependency: {exc}") except Exception as exc: print(f"Emotion UI error: {type(exc).__name__}: {exc}") return _empty_result("Emotion analysis is unavailable right now. Please check the terminal logs.") with gr.Blocks(title="Emotion Classifier") as interface: with gr.Column(elem_classes=["emotion-shell"]): gr.Markdown( """ # Emotion Classification DistilBERT-based emotion analysis with confidence and word-level evidence. """ ) status = gr.HTML(value=model_status()) with gr.Row(): with gr.Column(scale=5): text_input = gr.Textbox( lines=7, label="User message", placeholder="Example: I feel overwhelmed and I cannot sleep.", ) analyze_button = gr.Button("Analyze emotion", variant="primary") with gr.Column(scale=4): result_output = gr.HTML(label="Prediction") evidence_output = gr.Dataframe( headers=["Word", "Impact", "Confidence Without Word", "Effect"], datatype=["str", "number", "number", "str"], label="Word Evidence", interactive=False, ) summary_output = gr.HTML() analyze_button.click( fn=predict_emotion, inputs=text_input, outputs=[result_output, evidence_output, summary_output], ) if __name__ == "__main__": port = int(os.getenv("GRADIO_SERVER_PORT", "7860")) interface.launch(theme=THEME, css=CSS, server_port=port)