# --- 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" @app.route('/') def index(): """فایل اصلی HTML را نمایش می‌دهد.""" return render_template('index.html') @app.route('/chat', methods=['POST']) 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 ---