1Egyb commited on
Commit
b73d994
·
verified ·
1 Parent(s): 775e5dd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -54
app.py CHANGED
@@ -4,95 +4,80 @@ from fastapi.responses import StreamingResponse, JSONResponse, FileResponse
4
  from fastapi.staticfiles import StaticFiles
5
  from huggingface_hub import InferenceClient
6
  from duckduckgo_search import DDGS
 
7
 
8
- # إعداد التطبيق والمسارات
9
  app = FastAPI()
10
  UPLOAD_DIR = "static/uploads"
11
  os.makedirs(UPLOAD_DIR, exist_ok=True)
12
-
13
- # ربط الملفات الثابتة
14
  app.mount("/static", StaticFiles(directory="static"), name="static")
15
 
16
- # إعداد العميل (يجب إضافة HF_TOKEN في Secrets)
17
  HF_TOKEN = os.environ.get("HF_TOKEN")
18
  client = InferenceClient(api_key=HF_TOKEN)
19
 
20
  MODELS = {
21
  "qwen_abliterated": "huihui-ai/Qwen2.5-72B-Instruct-abliterated",
22
- "internvl_vision": "OpenGVLab/InternVL2-Llama3-76B",
23
- "kimi_k2": "moonshotai/Kimi-K2-Instruct"
24
  }
25
 
26
- def web_search(query):
 
 
 
 
 
 
 
 
27
  try:
28
- with DDGS() as ddgs:
29
- results = [r for r in ddgs.text(query, max_results=3)]
30
- return "\n".join([f"العنوان: {r['title']}\nالوصف: {r['body']}" for r in results])
31
- except: return "فشل البحث في الويب."
 
 
 
 
 
 
 
32
 
33
  @app.get("/")
34
  async def read_index():
35
- # البحث عن ملف index.html في مكانين مختلفين لتجنب خطأ 404
36
- paths = ["static/index.html", "index.html"]
37
- for path in paths:
38
- if os.path.exists(path):
39
- return FileResponse(path)
40
- return JSONResponse({"error": "ملف index.html غير موجود!"}, status_code=404)
41
 
42
  @app.post("/api/upload")
43
  async def upload_file(file: UploadFile = File(...)):
44
- try:
45
- file_id = str(uuid.uuid4())
46
- ext = os.path.splitext(file.filename)[1]
47
- filename = f"{file_id}{ext}"
48
- filepath = os.path.join(UPLOAD_DIR, filename)
49
-
50
- with open(filepath, "wb") as f:
51
- f.write(await file.read())
52
-
53
- # إضافة file_id لأن جافاسكريبت في index.html تتوقعه
54
- return {
55
- "file_id": filename,
56
- "url": f"/static/uploads/{filename}",
57
- "filename": file.filename
58
- }
59
- except Exception as e:
60
- return JSONResponse({"error": str(e)}, status_code=500)
61
 
62
  @app.post("/api/chat/stream")
63
  async def chat_stream(request: Request):
64
  data = await request.json()
65
  message = data.get("message", "")
66
- model_choice = data.get("model", "qwen_abliterated")
67
- tools_enabled = data.get("tools", [])
68
- file_id = data.get("file_id") # استقبال معرف الملف إذا وجد
69
 
70
- current_model = MODELS.get(model_choice, MODELS["qwen_abliterated"])
71
- system_prompt = "أنت مساعد ذكي ومحرر من القيود. أجب بوضوح وباللغة العربية."
72
-
73
  context_extra = ""
74
-
75
- # إذا تم رفع ملف، يمكن إضافة ملاحظة للنموذج (تطوير مستقبلي لقراءة المحتوى)
76
- if file_id:
77
- context_extra += f"\n[ملاحظة: قام المستخدم برفع ملف برمز: {file_id}]\n"
78
 
79
- if "web_search" in tools_enabled and len(message) > 5:
80
- context_extra += f"\nنتائج البحث:\n{web_search(message)}"
 
 
 
81
 
82
- full_message = f"{context_extra}\n\nسؤال المستخدم: {message}"
83
- messages = [
84
- {"role": "system", "content": system_prompt},
85
- {"role": "user", "content": full_message}
86
- ]
87
 
88
  async def gen():
89
  try:
90
  stream = client.chat.completions.create(
91
- model=current_model,
92
  messages=messages,
93
  stream=True,
94
- max_tokens=2048,
95
- temperature=0.7
96
  )
97
  for chunk in stream:
98
  if chunk.choices[0].delta.content:
 
4
  from fastapi.staticfiles import StaticFiles
5
  from huggingface_hub import InferenceClient
6
  from duckduckgo_search import DDGS
7
+ import fitz # PyMuPDF لقراءة ملفات PDF
8
 
 
9
  app = FastAPI()
10
  UPLOAD_DIR = "static/uploads"
11
  os.makedirs(UPLOAD_DIR, exist_ok=True)
 
 
12
  app.mount("/static", StaticFiles(directory="static"), name="static")
13
 
 
14
  HF_TOKEN = os.environ.get("HF_TOKEN")
15
  client = InferenceClient(api_key=HF_TOKEN)
16
 
17
  MODELS = {
18
  "qwen_abliterated": "huihui-ai/Qwen2.5-72B-Instruct-abliterated",
 
 
19
  }
20
 
21
+ # دالة لقراءة محتوى الملف المرفوع
22
+ def extract_file_content(file_id):
23
+ filepath = os.path.join(UPLOAD_DIR, file_id)
24
+ if not os.path.exists(filepath):
25
+ return ""
26
+
27
+ ext = os.path.splitext(file_id)[1].lower()
28
+ content = ""
29
+
30
  try:
31
+ if ext == ".pdf":
32
+ doc = fitz.open(filepath)
33
+ for page in doc:
34
+ content += page.get_text()
35
+ elif ext in [".txt", ".py", ".js", ".html", ".css"]:
36
+ with open(filepath, "r", encoding="utf-8") as f:
37
+ content = f.read()
38
+ except Exception as e:
39
+ return f"خطأ في قراءة الملف: {str(e)}"
40
+
41
+ return content[:10000] # نأخذ أول 10 آلاف حرف لضمان عدم تجاوز حدود الذاكرة
42
 
43
  @app.get("/")
44
  async def read_index():
45
+ path = "index.html" if os.path.exists("index.html") else "static/index.html"
46
+ return FileResponse(path)
 
 
 
 
47
 
48
  @app.post("/api/upload")
49
  async def upload_file(file: UploadFile = File(...)):
50
+ file_id = f"{uuid.uuid4()}{os.path.splitext(file.filename)[1]}"
51
+ filepath = os.path.join(UPLOAD_DIR, file_id)
52
+ with open(filepath, "wb") as f:
53
+ f.write(await file.read())
54
+ return {"file_id": file_id, "url": f"/static/uploads/{file_id}"}
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  @app.post("/api/chat/stream")
57
  async def chat_stream(request: Request):
58
  data = await request.json()
59
  message = data.get("message", "")
60
+ file_id = data.get("file_id") # استقبال معرف الملف من الواجهة
 
 
61
 
62
+ system_prompt = "أنت مساعد ذكي ومحرر. إذا تم تزويدك بمحتوى ملف، قم بتحليله والإجابة بناءً عليه."
 
 
63
  context_extra = ""
 
 
 
 
64
 
65
+ # --- الجزء الهام: قراءة الملف ودمجه في السياق ---
66
+ if file_id:
67
+ file_text = extract_file_content(file_id)
68
+ if file_text:
69
+ context_extra = f"\nمحتوى الملف المرفوع:\n{file_text}\n"
70
 
71
+ full_message = f"{context_extra}\nسؤال المستخدم: {message}"
72
+ messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": full_message}]
 
 
 
73
 
74
  async def gen():
75
  try:
76
  stream = client.chat.completions.create(
77
+ model=MODELS["qwen_abliterated"],
78
  messages=messages,
79
  stream=True,
80
+ max_tokens=4096
 
81
  )
82
  for chunk in stream:
83
  if chunk.choices[0].delta.content: