Spaces:
Sleeping
Sleeping
| # --- START OF FILE app.py --- | |
| import os | |
| import requests | |
| import json | |
| from flask import Flask, render_template, request, Response | |
| import logging | |
| # ================== بخش تنظیمات لاگنویسی (فارسی) ================== | |
| class PersianLogFormatter(logging.Formatter): | |
| LEVEL_MAP = { | |
| logging.DEBUG: "دیباگ", | |
| logging.INFO: "اطلاع", | |
| logging.WARNING: "هشدار", | |
| logging.ERROR: "خطا", | |
| logging.CRITICAL: "بحرانی", | |
| } | |
| def format(self, record): | |
| record.levelname = self.LEVEL_MAP.get(record.levelno, record.levelname) | |
| return super().format(record) | |
| def setup_logging(): | |
| log_format = '[%(asctime)s] [%(levelname)s]: %(message)s' | |
| date_format = '%Y-%m-%d %H:%M:%S' | |
| formatter = PersianLogFormatter(log_format, datefmt=date_format) | |
| root_logger = logging.getLogger() | |
| if root_logger.hasHandlers(): | |
| root_logger.handlers.clear() | |
| console_handler = logging.StreamHandler() | |
| console_handler.setFormatter(formatter) | |
| root_logger.addHandler(console_handler) | |
| root_logger.setLevel(logging.INFO) | |
| setup_logging() | |
| app = Flask(__name__) | |
| # آدرس API اسپیس Hugging Face که به عنوان بکاند عمل میکند | |
| HF_API_URL = "https://umint-ai.hf.space/api/chat" | |
| def index(): | |
| """فایل اصلی HTML را نمایش میدهد.""" | |
| return render_template('index.html') | |
| def chat(): | |
| """ | |
| این اندپوینت به عنوان یک پراکسی امن به اسپیس Hugging Face عمل میکند. | |
| درخواست چت را از فرانتاند دریافت کرده، آن را به اسپیس HF ارسال میکند، | |
| و پاسخ را بدون تغییر در فرمت SSE به کلاینت بازمیگرداند. | |
| """ | |
| data = request.json | |
| if not data: | |
| logging.error("درخواست نامعتبر: JSON وجود ندارد.") | |
| return Response(json.dumps({"error": "Invalid request"}), status=400, mimetype='application/json') | |
| # ساختار پیام را مطابق با نیاز اسپیس مقصد آماده میکنیم | |
| payload = { | |
| "messages": data.get("messages", []), | |
| "id": data.get("id", "chat_unknown"), | |
| "trigger": data.get("trigger", "submit-message") | |
| } | |
| logging.info(f"ارسال درخواست به HF Space برای چت {payload.get('id')}") | |
| def stream_response(): | |
| try: | |
| # ارسال درخواست به اسپیس دیگر و دریافت پاسخ به صورت استریم | |
| with requests.post(HF_API_URL, json=payload, stream=True, timeout=720) as response: | |
| response.raise_for_status() | |
| logging.info(f"اتصال موفقیتآمیز با HF Space برای چت {payload.get('id')}. در حال استریم پاسخ...") | |
| # ارسال مستقیم قطعههای خام برای حفظ مرزهای پیام SSE (مانند '\n\n') | |
| for chunk in response.iter_content(chunk_size=1024): | |
| yield chunk | |
| logging.info(f"استریم برای چت {payload.get('id')} به پایان رسید.") | |
| except requests.exceptions.RequestException as e: | |
| error_message = f"خطا در ارتباط با سرور چت: {e}" | |
| logging.error(error_message) | |
| error_payload = { | |
| "type": "error", | |
| "message": "متاسفانه در ارتباط با سرور اصلی خطایی رخ داد. لطفا دوباره تلاش کنید." | |
| } | |
| # ارسال پیام خطا در فرمت SSE | |
| yield f"data: {json.dumps(error_payload)}\n\n" | |
| return Response(stream_response(), mimetype='text/event-stream') | |
| if __name__ == '__main__': | |
| # این بخش فقط برای اجرای محلی است. در هاگینگ فیس از Gunicorn استفاده میشود. | |
| app.run(debug=True, host='0.0.0.0', port=os.environ.get("PORT", 7860)) | |
| # --- END OF FILE app.py --- |