Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| from streamlit_lottie import st_lottie | |
| import json | |
| # Cập nhật import | |
| from src.model_utils import ( | |
| load_sentiment_pipeline, | |
| predict_sentiment, | |
| MODEL_NAME, | |
| ) | |
| from src.database import init_db, add_entry, get_history, append_to_csv | |
| def load_lottiefile(filepath: str): | |
| try: | |
| with open(filepath, "r") as f: | |
| return json.load(f) | |
| except FileNotFoundError: | |
| return None | |
| except json.JSONDecodeError: | |
| st.error(f"File Lottie bị lỗi: {filepath}") | |
| return None | |
| def setup_ui(): | |
| st.set_page_config( | |
| page_title="Trợ lý Cảm xúc", | |
| page_icon="🤖", | |
| layout="centered" | |
| ) | |
| lottie_animation = load_lottiefile("robot.json") | |
| if lottie_animation: | |
| st_lottie(lottie_animation, speed=1, height=150, key="initial_animation") | |
| init_db() | |
| with st.spinner("Đang khởi động bộ não AI... 🧠"): | |
| sentiment_pipeline = load_sentiment_pipeline() | |
| # --- 3. GIAO DIỆN CHÍNH --- | |
| st.title("🤖 Trợ lý Phân loại Cảm xúc Tiếng Việt") | |
| st.caption(f"Model: {MODEL_NAME}") | |
| if sentiment_pipeline is not None: | |
| # Tạo form | |
| with st.form(key="sentiment_form"): | |
| user_input = st.text_area( | |
| "Nhập văn bản của bạn (từ 5 đến 50 ký tự):", | |
| "", | |
| height=150, | |
| max_chars=50 | |
| ) | |
| submit_button = st.form_submit_button( | |
| label="Phân loại ngay!", | |
| use_container_width=True | |
| ) | |
| if submit_button: | |
| raw_input = user_input.strip() | |
| if len(raw_input) < 5: | |
| st.error("Câu không hợp lệ (phải $\geq 5$ ký tự), thử lại.") | |
| else: | |
| with st.spinner("Trợ lý đang phân tích... 🤔"): | |
| label, score = predict_sentiment(raw_input, sentiment_pipeline) | |
| st.subheader("Kết quả:") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| if "POSITIVE" in label: | |
| st.success(f"**Cảm xúc: {label}**") | |
| elif "NEGATIVE" in label: | |
| st.error(f"**Cảm xúc: {label}**") | |
| else: | |
| st.info(f"**Cảm xúc: {label}**") | |
| with col2: | |
| st.metric(label="Độ tin cậy", value=f"{score:.2%}") | |
| st.markdown(f"> **Văn bản:** *{raw_input}*") | |
| try: | |
| add_entry(raw_input, label) | |
| append_to_csv(raw_input, label) | |
| except Exception as e: | |
| st.warning(f"Lỗi khi lưu CSDL hoặc csv: {e}") | |
| st.divider() | |
| with st.expander("Xem lịch sử phân loại (từ SQLite) 📖"): | |
| history = get_history() | |
| if history: | |
| df = pd.DataFrame(history, columns=["Thời gian", "Văn bản", "Nhãn"]) | |
| st.dataframe(df, use_container_width=True, hide_index=True) | |
| else: | |
| st.info("Chưa có lịch sử nào.") | |
| else: | |
| st.error("Không thể khởi chạy ứng dụng do lỗi tải pipeline mô hình.") |