khaterekhan2 / app.py
Jahadona's picture
Update app.py
d40654a verified
raw
history blame
6.53 kB
# این فایل app.py در Hugging Face Space شما قرار می گیرد
# این کد شامل:
# - بارگذاری مدل Sentence Transformer پارسی 'heydariAI/persian-embeddings'
# - تعریف اپلیکیشن Flask
# - اندپوینت /get_embedding برای دریافت سوال و ارسال بردار آن
# - **سرویس دهی فایل index.html به عنوان صفحه اصلی**
# - **سرویس دهی سایر فایل های ایستا (js, css, json)**
# - لاگ گیری برای عیب یابی در لاگ های Space و یک فایل جداگانه
# - مدیریت خطاهای اولیه در بارگذاری مدل و پردازش درخواست ها
from sentence_transformers import SentenceTransformer
from flask import Flask, request, jsonify, send_from_directory # <--- اضافه کردن send_from_directory
import numpy as np
import logging
import os
# import torch # اگر از GPU استفاده می کنید و torch نصب کرده اید، این خط را فعال نگه دارید.
# تنظیمات اولیه لاگینگ برای نمایش در لاگ های استاندارد Space
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# مسیر فایل لاگ جداگانه در فضای Hugging Face (برای عیب یابی بیشتر)
log_file_path = "app_log.txt"
# تابع برای افزودن پیام به فایل لاگ
def log_message(message):
try:
with open(log_file_path, "a", encoding="utf-8") as f:
f.write(message + "\n")
except Exception as e:
logging.error(f"Error writing to log file {log_file_path}: {e}")
# ****** نام مدل Sentence Transformer که می خواهیم در این سرور استفاده کنیم ******
# این مدل برای Space جدید: heydariAI/persian-embeddings
model_name_to_load = 'heydariAI/persian-embeddings'
# ***************************************************************************
# ****** بارگذاری مدل Sentence Transformer در هنگام راه اندازی سرور ******
logging.info(f"Attempting to load Sentence Transformer model: {model_name_to_load}...")
log_message(f"Attempting to load Sentence Transformer model: {model_name_to_load}...")
try:
# بارگذاری مدل. اگر GPU دارید و torch نصب شده، می توانید device='cuda' را اضافه کنید.
model = SentenceTransformer(model_name_to_load)
# ****** افزودن لاگ تأیید پس از بارگذاری موفق مدل ******
logging.info(f"SUCCESS: Model '{model_name_to_load}' loaded successfully.")
log_message(f"SUCCESS: Model '{model_name_to_load}' loaded successfully.")
# ******************************************************
except Exception as e:
# ****** مدیریت خطا در صورت عدم بارگذاری مدل ******
error_msg = f"ERROR: Failed to load model {model_name_to_load}: {e}"
logging.error(error_msg)
log_message(error_msg)
model = None
# *************************************************
# تعریف اپلیکیشن Flask
app = Flask(__name__)
# ****** اضافه کردن روت برای سرویس دهی فایل index.html به عنوان صفحه اصلی ******
# این روت وقتی کاربر به آدرس اصلی Space مراجعه می کند (/) اجرا می شود
@app.route('/')
def serve_index():
# فرض می کنیم index.html در ریشه دایرکتوری کاری اپلیکیشن (app/) قرار دارد
# send_from_directory فایل را از دایرکتوری مشخص شده ('.') ارسال می کند
return send_from_directory('.', 'index.html')
# ****** اضافه کردن روت برای سرویس دهی سایر فایل های ایستا ******
# این روت برای سرویس دهی فایل هایی مانند style.css, script.js, و فایل های JSON استفاده می شود.
# این روت هر فایلی که در ریشه اپلیکیشن قرار دارد و نام آن با روت های تعریف شده مطابقت ندارد را سرویس می دهد.
# <path:filename> یک متغیر مسیر است که شامل نام فایل و هر زیرپوشه ای است.
@app.route('/<path:filename>')
def serve_static(filename):
# اطمینان حاصل کنید که فایل در دایرکتوری کاری اپلیکیشن وجود دارد
# از send_from_directory برای جلوگیری از مشکلات امنیتی استفاده کنید.
logging.info(f"Attempting to serve static file: {filename}")
try:
return send_from_directory('.', filename)
except FileNotFoundError:
logging.error(f"Static file not found: {filename}")
return "File not found", 404 # برگرداندن خطای 404 اگر فایل پیدا نشد
# ****** اندپوینت اصلی برای دریافت بردار (embedding) سوال (همانند قبل) ******
@app.route('/get_embedding', methods=['POST'])
def get_embedding():
if model is None:
error_msg = "Model is not loaded on the server due to a previous error. Check Space logs."
log_message(f"Received request but model is not loaded: {error_msg}")
return jsonify({"error": error_msg}), 500
try:
data = request.get_json()
query = data.get('query')
if not query or not isinstance(query, str) or not query.strip():
log_message(f"Received invalid or empty query in /get_embedding: {data}")
return jsonify({"error": "Invalid or empty query text provided"}), 400
log_message(f"Received query in /get_embedding: '{query}'")
logging.info(f"Processing query in /get_embedding: '{query[:50]}...'")
embedding = model.encode(query, convert_to_numpy=True, pooling_mode='mean', normalize=True)
embedding_list = embedding.tolist()
log_message(f"Successfully generated embedding for query in /get_embedding.")
return jsonify({"embedding": embedding_list}), 200
except Exception as e:
error_message = f"An error occurred during embedding generation in /get_embedding: {e}"
logging.error(error_message)
log_message(error_message)
return jsonify({"error": error_message}), 500
# این بخش معمولاً در محیط Hugging Face Space توسط Gunicorn مدیریت می شود.
# if __name__ == '__main__':
# app.run(host='0.0.0.0', port=7860, debug=False)