Jahadona commited on
Commit
979d861
·
verified ·
1 Parent(s): cb2f022

Create server.py

Browse files
Files changed (1) hide show
  1. server.py +133 -0
server.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # این فایل server.py در Hugging Face Space شما قرار می گیرد
2
+ # این کد شامل:
3
+ # - بارگذاری مدل Sentence Transformer پارسی 'PartAI/Tooka-SBERT'
4
+ # - تعریف اپلیکیشن Flask
5
+ # - اندپوینت /get_embedding برای دریافت سوال و ارسال بردار آن
6
+ # - لاگ گیری برای عیب یابی در لاگ های Space و یک فایل جداگانه
7
+ # - مدیریت خطاهای اولیه در بارگذاری مدل و پردازش درخواست ها
8
+ # - رفع خطای 'SentenceTransformer' object has no attribute 'args' با اصلاح لاگ بارگذاری مدل
9
+
10
+ from sentence_transformers import SentenceTransformer
11
+ from flask import Flask, request, jsonify
12
+ import numpy as np
13
+ import logging
14
+ import os
15
+ # import torch # اگر از GPU استفاده می کنید و torch نصب کرده اید، این خط را فعال نگه دارید.
16
+
17
+ # تنظیمات اولیه لاگینگ برای نمایش در لاگ های استاندارد Space
18
+ # این لاگ ها معمولاً در تب "Container logs" دیده می شوند.
19
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
20
+
21
+ # مسیر فایل لاگ جداگانه در فضای Hugging Face (برای عیب یابی بیشتر)
22
+ # نکته: نوشتن در فایل در برخی محیط های Space ممکن است نیاز به تنظیمات مجوز داشته باشد.
23
+ # خطای [Errno 13] Permission denied در لاگ قبلی به همین دلیل بود.
24
+ log_file_path = "app_log.txt"
25
+
26
+ # تابع برای افزودن پیام به فایل لاگ
27
+ def log_message(message):
28
+ try:
29
+ # حالت 'a' برای اضافه کردن به انتهای فایل است.
30
+ # مطمئن شوید که دایرکتوری برای فایل قابل نوشتن است.
31
+ # اگر خطا مجوز می گیرید، می توانید این تابع را موقتا غیرفعال کنید یا مسیر دیگری را امتحان کنید.
32
+ with open(log_file_path, "a", encoding="utf-8") as f:
33
+ f.write(message + "\n")
34
+ except Exception as e:
35
+ # اگر نوشتن در فایل لاگ هم با خطا مواجه شد، در لاگ استاندارد Space بنویسید.
36
+ logging.error(f"Error writing to log file {log_file_path}: {e}")
37
+
38
+ # ****** نام مدل Sentence Transformer که می خواهیم در این سرور استفاده کنیم ******
39
+ # این مدل باید همان مدلی باشد که برای بردارسازی خاطرات در فایل های JSON استفاده کرده اید.
40
+ model_name_to_load = 'PartAI/Tooka-SBERT'
41
+ # ***************************************************************************
42
+
43
+
44
+ # ****** بارگذاری مدل Sentence Transformer در هنگام راه اندازی سرور ******
45
+ logging.info(f"Attempting to load Sentence Transformer model: {model_name_to_load}...") # لاگ قبل از بارگذاری (در لاگ های استاندارد Space)
46
+ log_message(f"Attempting to load Sentence Transformer model: {model_name_to_load}...") # لاگ قبل از بارگذاری (در فایل لاگ)
47
+
48
+ try:
49
+ # بارگذاری مدل. اگر GPU دارید و torch نصب شده، می توانید device='cuda' را اضافه کنید.
50
+ # اگر خطایی در بارگذاری رخ دهد، Exception گرفته می شود.
51
+ # model = SentenceTransformer(model_name_to_load, device='cuda' if torch.cuda.is_available() else 'cpu')
52
+ model = SentenceTransformer(model_name_to_load) # بارگذاری با استفاده از CPU یا تنظیمات پیش فرض
53
+
54
+ # ****** افزودن لاگ تأیید پس از بارگذاری موفق مدل ******
55
+ # این پیام ها در لاگ های Space به شما نشان می دهند که مدل با موفقیت بارگذاری شده و نام آن چیست.
56
+ # ما نام مدلی که قصد بارگذاریش را داشتیم لاگ می کنیم تا از خطای Attribute Error جلوگیری شود.
57
+ logging.info(f"SUCCESS: Model '{model_name_to_load}' loaded successfully.") # لاگ موفقیت (در لاگ های استاندارد Space)
58
+ log_message(f"SUCCESS: Model '{model_name_to_load}' loaded successfully.") # لاگ موفقیت (در فایل لاگ)
59
+ # ******************************************************
60
+
61
+ except Exception as e:
62
+ # ****** مدیریت خطا در صورت عدم بارگذاری مدل ******
63
+ error_msg = f"ERROR: Failed to load model {model_name_to_load}: {e}"
64
+ logging.error(error_msg) # لاگ خطا (در لاگ های استاندارد Space)
65
+ log_message(error_msg) # لاگ خطا (در فایل لاگ)
66
+ # در صورتی که بارگذاری مدل با خطا مواجه شد، متغیر model را None قرار می دهیم
67
+ # تا در تابع get_embedding بتوانیم وضعیت خطا را چک کنیم.
68
+ model = None
69
+ # *************************************************
70
+
71
+
72
+ # تعریف اپلیکیشن Flask
73
+ app = Flask(__name__)
74
+
75
+ # تعریف اندپوینت اصلی برای تست سلامت سرور
76
+ @app.route('/')
77
+ def index():
78
+ # چک کردن وضعیت مدل قبل از پاسخ به درخواست اصلی
79
+ if model is None:
80
+ # اگر مدل بارگذاری نشده، پیام خطا نمایش داده می شود.
81
+ return "Sentiment Embedding Server is running, but model failed to load. Check Space logs for details.", 500
82
+ # اگر مدل با موفقیت بارگذاری شده، پیام موفقیت نمایش داده می شود.
83
+ # از نام مدلی که در متغیر ذخیره کردیم استفاده می کنیم.
84
+ return f"Sentiment Embedding Server is running successfully with model: {model_name_to_load}"
85
+
86
+
87
+ # تعریف اندپوینت برای دریافت بردار (embedding) سوال
88
+ @app.route('/get_embedding', methods=['POST'])
89
+ def get_embedding():
90
+ # قبل از پردازش درخواست، مطمئن شوید مدل بارگذاری شده است.
91
+ if model is None:
92
+ error_msg = "Model is not loaded on the server due to a previous error. Check Space logs."
93
+ # این خطا احتمالا قبلا در لاگ ها ثبت شده، اما برای اطمینان مجدد ثبت می کنیم.
94
+ # logging.error(error_msg) # لاگ تکراری در صورتیکه بالا هم خطا داده
95
+ log_message(f"Received request but model is not loaded: {error_msg}") # ثبت در فایل لاگ
96
+ return jsonify({"error": error_msg}), 500 # ارسال پاسخ خطا با کد 500
97
+
98
+ try:
99
+ # دریافت داده ها از درخواست POST (باید شامل فیلد 'query' باشد)
100
+ data = request.get_json()
101
+ query = data.get('query')
102
+
103
+ # چک کردن اینکه فیلد query خالی نباشد
104
+ if not query or not isinstance(query, str) or not query.strip():
105
+ log_message(f"Received invalid or empty query in /get_embedding: {data}")
106
+ return jsonify({"error": "Invalid or empty query text provided"}), 400 # ارسال پاسخ خطا با کد 400
107
+
108
+ log_message(f"Received query in /get_embedding: '{query}'")
109
+ logging.info(f"Processing query in /get_embedding: '{query[:50]}...'") # لاگ در کنسول Space برای درخواست های دریافتی
110
+
111
+ embedding = model.encode(query, convert_to_numpy=True, pooling_mode='mean', normalize=True)
112
+
113
+ # تبدیل بردار numpy به لیست Python برای ارسال در پاسخ JSON
114
+ embedding_list = embedding.tolist()
115
+
116
+ log_message(f"Successfully generated embedding for query in /get_embedding.") # لاگ موفقیت در فایل
117
+ # logging.info(f"Embedding generated successfully for query.") # لاگ موفقیت در کنسول Space (اختیاری)
118
+
119
+ # ارسال بردار به عنوان پاسخ JSON
120
+ return jsonify({"embedding": embedding_list}), 200 # ارسال پاسخ موفقیت با کد 200
121
+
122
+ except Exception as e:
123
+ error_message = f"An error occurred during embedding generation in /get_embedding: {e}"
124
+ logging.error(error_message) # لاگ خطا (در لاگ های استاندارد Space)
125
+ log_message(error_message) # لاگ خطا (در فایل لاگ)
126
+ return jsonify({"error": error_message}), 500 # ارسال پاسخ خطا با کد 500
127
+
128
+ # خط زیر فقط در صورتی که فایل server.py مستقیماً اجرا شود، سرور Flask را اجرا می کند.
129
+ # در Hugging Face Space، خود زیرساخت Space مسئول اجرای برنامه شماست و این بخش معمولاً غیرفعال است.
130
+ # if __name__ == '__main__':
131
+ # # Hugging Face Spaces از پورت 7860 استفاده می کند.
132
+ # # debug=True برای محیط توسعه مفید است اما در محیط پروداکشن توصیه نمی شود.
133
+ # app.run(host='0.0.0.0', port=7860, debug=False)