Riy777 commited on
Commit
b4f9a00
·
verified ·
1 Parent(s): 7708084

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -15
app.py CHANGED
@@ -20,6 +20,11 @@ import uvicorn
20
  import random
21
  import docx # لإضافة دعم .docx
22
 
 
 
 
 
 
23
  # ========== تكوين السجلات ==========
24
  logging.basicConfig(
25
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
@@ -45,7 +50,18 @@ REPO_ID = "Riy777/Study"
45
  SELECTING_SUBJECT, SELECTING_ACTION, WAITING_FOR_QUESTION = range(3)
46
 
47
  # ========== تطبيق FastAPI ==========
48
- app = FastAPI(title="Medical Lab Bot", version="1.0.0")
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  # ========== فئة البوت الرئيسية ==========
51
  class MedicalLabBot:
@@ -59,23 +75,32 @@ class MedicalLabBot:
59
  self.load_all_materials()
60
 
61
  async def initialize_application(self):
62
- """تهيئة تطبيق التليجرام بشكل غير متزامن مع محاولات إعادة (للتشغيل في الخلفية)"""
63
  try:
64
  if self.is_initialized:
65
  return True
66
 
67
  logger.info("🔄 جاري تهيئة تطبيق التليجرام...")
 
 
 
 
 
 
 
 
 
 
68
  self.application = (
69
  Application.builder()
70
  .token(TELEGRAM_BOT_TOKEN)
 
71
  .build()
72
  )
73
  await self.setup_handlers()
74
 
75
- # ========== !! الحــل !! ==========
76
- # زيادة المحاولات والتأخير بشكل كبير للتعامل مع بطء شبكة HFS
77
- max_retries = 5 # زيادة إلى 5 محاولات
78
- retry_delay = 10 # زيادة إلى 10 ثواني
79
 
80
  for attempt in range(max_retries):
81
  try:
@@ -109,7 +134,7 @@ class MedicalLabBot:
109
  logger.info(f"⏳ الانتظار {retry_delay} ثواني قبل إعادة المحاولة...")
110
  await asyncio.sleep(retry_delay)
111
  else:
112
- logger.error(f"❌ فشل تهيئة التطبيق نهائياً بعد {max_retries} محاولات.")
113
 
114
  # فشل بعد كل المحاولات
115
  self.is_initialized = False
@@ -520,7 +545,7 @@ class MedicalLabBot:
520
  keyboard.append([InlineKeyboardButton(display_name, callback_data=f"subject_{subject}")])
521
 
522
  keyboard.append([InlineKeyboardButton("🔄 تحديث قائمة المواد", callback_data="refresh_materials")])
523
- keyboard.append([InlineKeyboardButton("❓ مساعدة", callback_data="general_help")])
524
  return keyboard
525
 
526
  async def handle_subject_selection(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
@@ -783,13 +808,15 @@ class MedicalLabBot:
783
  bot = MedicalLabBot()
784
 
785
  # ========== دوال FastAPI ==========
786
- @app.on_event("startup")
787
- async def on_startup():
788
- """بدء تشغيل التطبيق وبدء تهيئة البوت في الخلفية"""
789
- logger.info("🚀 بدء تشغيل FastAPI... بدء مهمة تهيئة البوت في الخلفية.")
790
- # لا ننتظر (no await) - سيبدأ الخادم فوراً، ��ستعمل هذه المهمة في الخلفية
791
- asyncio.create_task(bot.initialize_application())
792
- logger.info("✅ خادم FastAPI يعمل. التهيئة (الاتصال بـ Telegram) جارية في الخلفية.")
 
 
793
 
794
  @app.get("/", response_class=HTMLResponse)
795
  async def root():
 
20
  import random
21
  import docx # لإضافة دعم .docx
22
 
23
+ # ========== (الحل) إضافة المكتبات اللازمة لحل مشكلة DNS ==========
24
+ import httpx
25
+ import httpx_dnspython
26
+ # ==========================================================
27
+
28
  # ========== تكوين السجلات ==========
29
  logging.basicConfig(
30
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 
50
  SELECTING_SUBJECT, SELECTING_ACTION, WAITING_FOR_QUESTION = range(3)
51
 
52
  # ========== تطبيق FastAPI ==========
53
+ # تعديل: استخدام lifespan بدلاً من on_event
54
+ @asyncio.contextmanager
55
+ async def lifespan(app: FastAPI):
56
+ # الكود الذي كان في on_startup
57
+ logger.info("🚀 بدء تشغيل FastAPI... بدء مهمة تهيئة البوت في الخلفية.")
58
+ asyncio.create_task(bot.initialize_application())
59
+ logger.info("✅ خادم FastAPI يعمل. التهيئة (الاتصال بـ Telegram) جارية في الخلفية.")
60
+ yield
61
+ # كود إيقاف التشغيل (on_shutdown) (إن وجد)
62
+ logger.info("🛑 إيقاف تشغيل خادم FastAPI.")
63
+
64
+ app = FastAPI(title="Medical Lab Bot", version="1.0.0", lifespan=lifespan)
65
 
66
  # ========== فئة البوت الرئيسية ==========
67
  class MedicalLabBot:
 
75
  self.load_all_materials()
76
 
77
  async def initialize_application(self):
78
+ """تهيئة تطبيق التليجرام بشكل غير متزامن مع حل DNS المخصص"""
79
  try:
80
  if self.is_initialized:
81
  return True
82
 
83
  logger.info("🔄 جاري تهيئة تطبيق التليجرام...")
84
+
85
+ # ========== !! الحل الجذري (DNS) !! ==========
86
+ logger.info("🔧 إعداد عميل HTTP مخصص مع DNS (1.1.1.1)...")
87
+ transport = httpx_dnspython.AsyncDNSTransport(
88
+ resolver=httpx_dnspython.SyncResolver(nameservers=["1.1.1.1", "8.8.8.8"])
89
+ )
90
+ # نستخدم httpx.AsyncClient مع الناقل المخصص
91
+ custom_client = httpx.AsyncClient(transport=transport)
92
+ # ============================================
93
+
94
  self.application = (
95
  Application.builder()
96
  .token(TELEGRAM_BOT_TOKEN)
97
+ .http_client(custom_client) # <-- تمرير العميل المخصص هنا
98
  .build()
99
  )
100
  await self.setup_handlers()
101
 
102
+ max_retries = 3 # تقليل المحاولات لأن المشكلة يفترض أن تُحل
103
+ retry_delay = 5 # تقليل التأخير
 
 
104
 
105
  for attempt in range(max_retries):
106
  try:
 
134
  logger.info(f"⏳ الانتظار {retry_delay} ثواني قبل إعادة المحاولة...")
135
  await asyncio.sleep(retry_delay)
136
  else:
137
+ logger.error(f"❌ فشل تهيئة التطبيق نهائياً بعد {max_retries} محاولات (حتى مع DNS المخصص).")
138
 
139
  # فشل بعد كل المحاولات
140
  self.is_initialized = False
 
545
  keyboard.append([InlineKeyboardButton(display_name, callback_data=f"subject_{subject}")])
546
 
547
  keyboard.append([InlineKeyboardButton("🔄 تحديث قائمة المواد", callback_data="refresh_materials")])
548
+ keyboard.append([InlineKeyboardButton("❓ مساعدة", callback_Ddata="general_help")])
549
  return keyboard
550
 
551
  async def handle_subject_selection(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
 
808
  bot = MedicalLabBot()
809
 
810
  # ========== دوال FastAPI ==========
811
+
812
+ # تم نقل @app.on_event("startup") إلى تعريف "lifespan"
813
+ # @app.on_event("startup")
814
+ # async def on_startup():
815
+ # """بدء تشغيل التطبيق وبدء تهيئة البوت في الخلفية"""
816
+ # logger.info("🚀 بدء تشغيل FastAPI... بدء مهمة تهيئة البوت في الخلفية.")
817
+ # # لا ننتظر (no await) - سيبدأ الخادم فوراً، وستعمل هذه المهمة في الخلفية
818
+ # asyncio.create_task(bot.initialize_application())
819
+ # logger.info("✅ خادم FastAPI يعمل. التهيئة (الاتصال بـ Telegram) جارية في الخلفية.")
820
 
821
  @app.get("/", response_class=HTMLResponse)
822
  async def root():