Spaces:
Running
Running
File size: 5,412 Bytes
0d7a9c0 0490e30 b0cb70a bca7346 b0cb70a 609e909 0d7a9c0 0490e30 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a bca7346 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 b0cb70a 0d7a9c0 bd64212 0d7a9c0 b0cb70a 0d7a9c0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
from flask import Flask, request, jsonify
from flask_cors import CORS
import logging
from pyvi import ViTokenizer
# Cấu hình logging cho app
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
from model import predict_sentiment_3sentiment, predict_sentiment_5sentiment
import pandas as pd
# Khởi tạo Flask app
app = Flask(__name__)
CORS(app)
# Xử lý encoding cho tiếng Việt để hiển thị đúng trong response
app.config['JSON_AS_ASCII'] = False
@app.route("/predict", methods=['POST'])
def predict():
"""
Dự đoán cảm xúc từ văn bản đầu vào.
Request body phải là JSON có dạng: {"text": "nội dung bình luận"}
"""
# Lấy dữ liệu JSON từ request
json_data = request.get_json()
logger.info(f"Received predict request: {json_data}")
# Kiểm tra xem key 'text' có tồn tại và không rỗng không
if not json_data or 'text' not in json_data or not json_data.get('text', '').strip():
logger.warning("Missing 'text' in request")
return jsonify({"error": "Vui lòng cung cấp trường 'text' trong request body."}), 400
# Kiểm tra xem key 'type' có tồn tại và không rỗng không
if not json_data or 'type' not in json_data or not json_data.get('type', '').strip():
logger.warning("Missing 'type' in request")
return jsonify({"error": "Vui lòng cung cấp trường 'type' trong request body."}), 400
# Lấy văn bản từ dữ liệu
text_to_predict = json_data['text']
sentiment_type = json_data['type']
# Gọi hàm dự đoán từ model
try:
if sentiment_type == "3sentiment":
text_to_predict = ViTokenizer.tokenize(text_to_predict)
sentiment, score = predict_sentiment_3sentiment(text_to_predict)
elif sentiment_type == "5sentiment":
sentiment, score = predict_sentiment_5sentiment(text_to_predict)
except Exception as e:
logger.error(f"Prediction error: {e}")
return jsonify({"error": str(e)}), 500
# Tạo response
response = {
"comment": text_to_predict,
"sentiment": sentiment,
"confidence": score
}
return jsonify(response)
@app.route("/")
def read_root():
return jsonify({"message": "Chào mừng đến với API Phân tích Cảm xúc sử dụng Flask!"})
@app.route("/predict-batch", methods=['POST'])
def predict_batch():
"""
Dự đoán cảm xúc cho một loạt bình luận từ file Excel.
File Excel phải được gửi dưới dạng form-data với key là 'file'.
Cột đầu tiên của file Excel sẽ được sử dụng làm cột chứa bình luận.
"""
# 1. Kiểm tra xem có file trong request không
if 'file' not in request.files:
logger.warning("No file part in request")
return jsonify({"error": "Không tìm thấy file trong request (key phải là 'file')."}), 400
# Dữ liệu form đi kèm với file sẽ nằm trong request.form
sentiment_type = request.form.get('type')
logger.info(f"Received batch predict request for type: {sentiment_type}")
# Kiểm tra xem key 'type' có tồn tại và không rỗng không
if not sentiment_type or sentiment_type.strip() not in ["3sentiment", "5sentiment"]:
logger.warning("Invalid or missing 'type'")
return jsonify({"error": "Vui lòng cung cấp trường 'type' (3sentiment hoặc 5sentiment) trong form data."}), 400
file = request.files['file']
# 2. Kiểm tra xem người dùng có chọn file không
if file.filename == '':
logger.warning("No selected file")
return jsonify({"error": "Chưa chọn file nào."}), 400
# 3. Kiểm tra định dạng file
if not file.filename.endswith(('.xlsx', '.xls')):
logger.warning(f"Invalid file format: {file.filename}")
return jsonify({"error": "Định dạng file không hợp lệ. Vui lòng sử dụng file .xlsx hoặc .xls."}), 400
try:
# 4. Đọc file Excel bằng pandas, sử dụng engine openpyxl
df = pd.read_excel(file, engine='openpyxl')
if df.empty:
return jsonify({"error": "File Excel rỗng."}), 400
# Lấy tên cột đầu tiên để xử lý
comments_column = df.columns[0]
results = []
# 5. Lặp qua từng bình luận (bỏ qua các dòng rỗng) để dự đoán
for comment in df[comments_column].dropna().astype(str):
if sentiment_type == "3sentiment":
sentiment, score = predict_sentiment_3sentiment(comment)
elif sentiment_type == "5sentiment":
sentiment, score = predict_sentiment_5sentiment(comment)
results.append({"comment": comment, "sentiment": sentiment, "confidence": f"{score:.2%}"})
return jsonify(results)
except Exception as e:
logger.error(f"Error processing batch file: {e}")
return jsonify({"error": f"Đã xảy ra lỗi khi xử lý file: {str(e)}"}), 500
if __name__ == "__main__":
# Chạy app ở chế độ debug để tự động reload khi có thay đổi
# host='0.0.0.0' để có thể truy cập từ bên ngoài network
# Lưu ý: Không sử dụng debug=True trong môi trường production
app.run(host="0.0.0.0", port=8000, debug=True) |