from flask import Flask, render_template, request, jsonify from app_backend import EmotionClassifier, HistoryDB import threading import traceback import logging from functools import wraps # from fastapi import FastAPI # app = FastAPI() # @app.get("/") # def greet_json(): # return {"Hello": "World!"} # --- Khởi tạo Flask --- app = Flask(__name__, static_folder="static", template_folder="html") # --- Cấu hình hệ thống ghi log --- logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') # --- Khai báo biến global cho mô hình và cơ sở dữ liệu --- clf = None db = None init_lock = threading.Lock() # --- Khởi tạo backend --- def init_backend(): global clf, db with init_lock: if clf is None or db is None: try: clf = EmotionClassifier() db = HistoryDB() logging.info("Khởi tạo backend thành công") except Exception as e: logging.error(f"Khởi tạo backend thất bại: {e}") traceback.print_exc() # --- Đảm bảo backend luôn được khởi tạo --- def ensure_backend(func): @wraps(func) def wrapper(*args, **kwargs): global clf, db if clf is None or db is None: init_backend() return jsonify({'error': 'Backend không được khởi tạo'}), 500 return func(*args, **kwargs) return wrapper def validate_text(text): text = (text or '').strip() return None, text def record_to_dict(row): return { 'id': row[0], 'text': row[1], 'label': row[2], 'timestamp': row[3] } @app.route('/') def index(): return render_template('index.html') # --- Hàm dự đoán phân loại --- @app.route('/api/predict', methods=['POST']) @ensure_backend def predict(): global clf, db try: data = request.get_json() text = (data.get('text') if data else '').strip() error, text = validate_text(text) if error: return jsonify({'error': error}), 400 # --- Phân loại cảm xúc --- result = clf.predict(text) pred_label = result.get('sentiment') conf = max(result.get('probs') or [0]) # --- Lưu kết quả vào lịch sử --- rowid = db.add(text, pred_label) rec = db.list_all(1)[0] saved_record = record_to_dict(rec) return jsonify({ 'id': rowid, 'text': saved_record['text'], 'label': saved_record['label'], 'confidence': round(conf * 100, 1), 'timestamp': saved_record['timestamp'] }), 200 except Exception as e: logging.error(f"Lỗi dự đoán: {e}") traceback.print_exc() return jsonify({'error': f'Lỗi phân loại: {str(e)}'}), 500 # --- Hàm "get_history" và "clear_history" để quản lý lịch sử phân loại --- @app.route('/api/history', methods=['GET']) @ensure_backend def get_history(): # --- Lấy 50 bản ghi lịch sử phân loại --- global db try: records = db.list_all(limit=50) history = [record_to_dict(row) for row in records] return jsonify(history), 200 except Exception as e: logging.error(f"Lỗi lịch sử phân loại: {e}") return jsonify({'error': str(e)}), 500 @app.route('/api/clear-history', methods=['POST']) @ensure_backend def clear_history(): global db try: with db.conn: db.conn.execute("DELETE FROM history") return jsonify({'message': 'Đã xóa toàn bộ lịch sử'}), 200 except Exception as e: logging.error(f"Lỗi xóa lịch sử phân loại: {e}") return jsonify({'error': str(e)}), 500 # --- Chạy server --- if __name__ == '__main__': init_backend() app.run(debug=True, host='127.0.0.1', port=5000, threaded=True)