Update app.py
Browse files
app.py
CHANGED
|
@@ -15,7 +15,7 @@ from PIL import Image
|
|
| 15 |
import io
|
| 16 |
import requests
|
| 17 |
from fastapi import FastAPI, Request, HTTPException
|
| 18 |
-
from fastapi.responses import HTMLResponse
|
| 19 |
import uvicorn
|
| 20 |
import random
|
| 21 |
import docx # لإضافة دعم .docx
|
|
@@ -25,7 +25,7 @@ import httpx
|
|
| 25 |
import dns.asyncresolver
|
| 26 |
from httpx import AsyncClient, AsyncHTTPTransport, Request, Response
|
| 27 |
import contextlib # <-- إضافة المكتبة الصحيحة
|
| 28 |
-
from typing import Dict # <-- إضافة Dict
|
| 29 |
# ==========================================================
|
| 30 |
|
| 31 |
# ========== تكوين السجلات ==========
|
|
@@ -192,7 +192,7 @@ class MedicalLabBot:
|
|
| 192 |
return False
|
| 193 |
|
| 194 |
except Exception as e:
|
| 195 |
-
logger.error(f"❌ خطأ فادح في تهيئة التطبيق: {e}")
|
| 196 |
self.is_initialized = False
|
| 197 |
self.initialization_status = "failed"
|
| 198 |
return False
|
|
@@ -361,6 +361,7 @@ class MedicalLabBot:
|
|
| 361 |
async def _call_nvidia_api(self, messages, max_tokens=1500):
|
| 362 |
"""دالة مساعدة لاستدعاء NVIDIA API"""
|
| 363 |
try:
|
|
|
|
| 364 |
completion = await asyncio.to_thread(
|
| 365 |
nvidia_client.chat.completions.create,
|
| 366 |
model="meta/llama3-70b-instruct", # استخدام موديل قوي
|
|
@@ -371,7 +372,7 @@ class MedicalLabBot:
|
|
| 371 |
)
|
| 372 |
return completion.choices[0].message.content
|
| 373 |
except Exception as e:
|
| 374 |
-
logger.error(f"❌ Error calling NVIDIA API: {e}")
|
| 375 |
return f"❌ حدث خطأ أثناء التواصل مع الذكاء الاصطناعي: {e}"
|
| 376 |
|
| 377 |
def _find_file_by_query(self, query, subject):
|
|
@@ -452,16 +453,16 @@ class MedicalLabBot:
|
|
| 452 |
if local_path.lower().endswith('.pdf'):
|
| 453 |
# استخدام PyMuPDF (fitz) لاستخراج أدق
|
| 454 |
with fitz.open(local_path) as doc:
|
| 455 |
-
for page in doc:
|
| 456 |
text_content += page.get_text("text", sort=True) # محاولة فرز النص
|
| 457 |
-
text_content += "\n\n--- Page
|
| 458 |
|
| 459 |
elif local_path.lower().endswith('.txt'):
|
| 460 |
with open(local_path, 'r', encoding='utf-8', errors='ignore') as f: # تجاهل أخطاء الترميز
|
| 461 |
text_content = f.read()
|
| 462 |
|
| 463 |
elif local_path.lower().endswith('.docx'):
|
| 464 |
-
doc_obj = docx.Document
|
| 465 |
full_text = []
|
| 466 |
for para in doc_obj.paragraphs:
|
| 467 |
full_text.append(para.text)
|
|
@@ -1083,7 +1084,7 @@ async def root():
|
|
| 1083 |
</html>
|
| 1084 |
"""
|
| 1085 |
|
| 1086 |
-
# ========== !! الحل
|
| 1087 |
@app.post("/telegram", response_model=Dict[str, str])
|
| 1088 |
async def handle_telegram_update(request: Request):
|
| 1089 |
"""معالجة تحديثات Telegram"""
|
|
@@ -1116,7 +1117,8 @@ async def handle_telegram_update(request: Request):
|
|
| 1116 |
raise HTTPException(status_code=500, detail="Internal server error while processing update")
|
| 1117 |
|
| 1118 |
|
| 1119 |
-
|
|
|
|
| 1120 |
async def health_check():
|
| 1121 |
"""فحص صحة الخدمة"""
|
| 1122 |
materials_count = len(bot.available_materials)
|
|
@@ -1146,7 +1148,6 @@ async def health_check():
|
|
| 1146 |
}
|
| 1147 |
|
| 1148 |
# استخدام JSONResponse لتحديد status_code بشكل صحيح
|
| 1149 |
-
from fastapi.responses import JSONResponse
|
| 1150 |
return JSONResponse(content=response_payload, status_code=status_code)
|
| 1151 |
|
| 1152 |
# ========== التشغيل الرئيسي ==========
|
|
|
|
| 15 |
import io
|
| 16 |
import requests
|
| 17 |
from fastapi import FastAPI, Request, HTTPException
|
| 18 |
+
from fastapi.responses import HTMLResponse, JSONResponse # استيراد JSONResponse
|
| 19 |
import uvicorn
|
| 20 |
import random
|
| 21 |
import docx # لإضافة دعم .docx
|
|
|
|
| 25 |
import dns.asyncresolver
|
| 26 |
from httpx import AsyncClient, AsyncHTTPTransport, Request, Response
|
| 27 |
import contextlib # <-- إضافة المكتبة الصحيحة
|
| 28 |
+
from typing import Dict, Any # <-- إضافة Dict و Any
|
| 29 |
# ==========================================================
|
| 30 |
|
| 31 |
# ========== تكوين السجلات ==========
|
|
|
|
| 192 |
return False
|
| 193 |
|
| 194 |
except Exception as e:
|
| 195 |
+
logger.error(f"❌ خطأ فادح في تهيئة التطبيق: {e}", exc_info=True) # إضافة exc_info=True
|
| 196 |
self.is_initialized = False
|
| 197 |
self.initialization_status = "failed"
|
| 198 |
return False
|
|
|
|
| 361 |
async def _call_nvidia_api(self, messages, max_tokens=1500):
|
| 362 |
"""دالة مساعدة لاستدعاء NVIDIA API"""
|
| 363 |
try:
|
| 364 |
+
# استخدام asyncio.to_thread لتشغيل الكود المتزامن في thread
|
| 365 |
completion = await asyncio.to_thread(
|
| 366 |
nvidia_client.chat.completions.create,
|
| 367 |
model="meta/llama3-70b-instruct", # استخدام موديل قوي
|
|
|
|
| 372 |
)
|
| 373 |
return completion.choices[0].message.content
|
| 374 |
except Exception as e:
|
| 375 |
+
logger.error(f"❌ Error calling NVIDIA API: {e}", exc_info=True)
|
| 376 |
return f"❌ حدث خطأ أثناء التواصل مع الذكاء الاصطناعي: {e}"
|
| 377 |
|
| 378 |
def _find_file_by_query(self, query, subject):
|
|
|
|
| 453 |
if local_path.lower().endswith('.pdf'):
|
| 454 |
# استخدام PyMuPDF (fitz) لاستخراج أدق
|
| 455 |
with fitz.open(local_path) as doc:
|
| 456 |
+
for page_num, page in enumerate(doc):
|
| 457 |
text_content += page.get_text("text", sort=True) # محاولة فرز النص
|
| 458 |
+
# text_content += f"\n\n--- Page {page_num + 1} ---\n\n" # إضافة فاصل صفحات (اختياري)
|
| 459 |
|
| 460 |
elif local_path.lower().endswith('.txt'):
|
| 461 |
with open(local_path, 'r', encoding='utf-8', errors='ignore') as f: # تجاهل أخطاء الترميز
|
| 462 |
text_content = f.read()
|
| 463 |
|
| 464 |
elif local_path.lower().endswith('.docx'):
|
| 465 |
+
doc_obj = await asyncio.to_thread(docx.Document, local_path) # تشغيل في thread
|
| 466 |
full_text = []
|
| 467 |
for para in doc_obj.paragraphs:
|
| 468 |
full_text.append(para.text)
|
|
|
|
| 1084 |
</html>
|
| 1085 |
"""
|
| 1086 |
|
| 1087 |
+
# ========== !! الحل البديل المضمون: تحديد نوع الاستجابة صراحة !! ==========
|
| 1088 |
@app.post("/telegram", response_model=Dict[str, str])
|
| 1089 |
async def handle_telegram_update(request: Request):
|
| 1090 |
"""معالجة تحديثات Telegram"""
|
|
|
|
| 1117 |
raise HTTPException(status_code=500, detail="Internal server error while processing update")
|
| 1118 |
|
| 1119 |
|
| 1120 |
+
# ========== تعديل احترازي: تحديد نوع الاستجابة لمسار health أيضاً ==========
|
| 1121 |
+
@app.get("/health", response_model=Dict[str, Any])
|
| 1122 |
async def health_check():
|
| 1123 |
"""فحص صحة الخدمة"""
|
| 1124 |
materials_count = len(bot.available_materials)
|
|
|
|
| 1148 |
}
|
| 1149 |
|
| 1150 |
# استخدام JSONResponse لتحديد status_code بشكل صحيح
|
|
|
|
| 1151 |
return JSONResponse(content=response_payload, status_code=status_code)
|
| 1152 |
|
| 1153 |
# ========== التشغيل الرئيسي ==========
|