Spaces:
Runtime error
Runtime error
| # این فایل 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 مراجعه می کند (/) اجرا می شود | |
| def serve_index(): | |
| # فرض می کنیم index.html در ریشه دایرکتوری کاری اپلیکیشن (app/) قرار دارد | |
| # send_from_directory فایل را از دایرکتوری مشخص شده ('.') ارسال می کند | |
| return send_from_directory('.', 'index.html') | |
| # ****** اضافه کردن روت برای سرویس دهی سایر فایل های ایستا ****** | |
| # این روت برای سرویس دهی فایل هایی مانند style.css, script.js, و فایل های JSON استفاده می شود. | |
| # این روت هر فایلی که در ریشه اپلیکیشن قرار دارد و نام آن با روت های تعریف شده مطابقت ندارد را سرویس می دهد. | |
| # <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) سوال (همانند قبل) ****** | |
| 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) |