bahi-bh commited on
Commit
eff0ae0
·
verified ·
1 Parent(s): f79a166

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -148
app.py CHANGED
@@ -31,21 +31,19 @@ DEEPSEEK_EMAIL = os.getenv("DEEPSEEK_EMAIL", "").strip()
31
  DEEPSEEK_PASSWORD = os.getenv("DEEPSEEK_PASSWORD", "").strip()
32
  DEEPSEEK_EMAIL_2 = os.getenv("DEEPSEEK_EMAIL_2", "").strip()
33
  DEEPSEEK_PASSWORD_2 = os.getenv("DEEPSEEK_PASSWORD_2", "").strip()
34
- DEEPSEEK_TOKEN = os.getenv("DEEPSEEK_TOKEN", "").strip()
35
- DEEPSEEK_TOKEN_2 = os.getenv("DEEPSEEK_TOKEN_2", "").strip()
36
 
37
  ACCOUNTS = []
38
  if DEEPSEEK_EMAIL and DEEPSEEK_PASSWORD:
39
  ACCOUNTS.append({
40
  "email": DEEPSEEK_EMAIL,
41
  "password": DEEPSEEK_PASSWORD,
42
- "token": DEEPSEEK_TOKEN or ""
43
  })
44
  if DEEPSEEK_EMAIL_2 and DEEPSEEK_PASSWORD_2:
45
  ACCOUNTS.append({
46
  "email": DEEPSEEK_EMAIL_2,
47
  "password": DEEPSEEK_PASSWORD_2,
48
- "token": DEEPSEEK_TOKEN_2 or ""
49
  })
50
 
51
  WASM_PATH = os.getenv("WASM_PATH", "./sha3_wasm_bg.7b9ca65ddd.wasm")
@@ -54,7 +52,6 @@ WASM_URL = "https://raw.githubusercontent.com/iidamie/deepseek2api/main/sha3_was
54
  KEEP_ALIVE_TIMEOUT = 5
55
  CLAUDE_DEFAULT_MODEL = "claude-sonnet-4-20250514"
56
 
57
-
58
  # ============================================================
59
  # Logging
60
  # ============================================================
@@ -91,16 +88,13 @@ templates = Jinja2Templates(directory="templates")
91
  # ============================================================
92
 
93
  def download_wasm_file():
94
- """تحميل ملف WASM من GitHub إذا كان مفقوداً"""
95
  try:
96
  logger.info(f"محاولة تحميل WASM من: {WASM_URL}")
97
  urllib.request.urlretrieve(WASM_URL, WASM_PATH)
98
  if os.path.isfile(WASM_PATH):
99
  logger.info(f"تم تحميل WASM بنجاح إلى: {os.path.abspath(WASM_PATH)}")
100
  return True
101
- else:
102
- logger.error("فشل تحميل WASM: الملف لم يتم إنشاؤه")
103
- return False
104
  except Exception as e:
105
  logger.error(f"فشل تحميل WASM: {e}")
106
  return False
@@ -132,7 +126,7 @@ BASE_HEADERS = {
132
 
133
 
134
  # ============================================================
135
- # Startup event with WASM auto-download
136
  # ============================================================
137
 
138
  @app.on_event("startup")
@@ -147,40 +141,36 @@ async def startup_event():
147
  for acc in ACCOUNTS:
148
  logger.info(" - %s", acc.get("email"))
149
  else:
150
- logger.warning("No accounts configured. Please set DEEPSEEK_EMAIL and DEEPSEEK_PASSWORD.")
151
 
152
- # التحقق من وجود ملف WASM وتحميله تلقائياً
153
  if not os.path.isfile(WASM_PATH):
154
- logger.warning(f"ملف WASM غير موجود: {os.path.abspath(WASM_PATH)}")
155
- logger.info("محاولة تحميل الملف تلقائياً...")
156
  if download_wasm_file():
157
- logger.info("تم تحميل WASM بنجاح")
158
  else:
159
- logger.critical("فشل تحميل WASM. سيعمل التطبيق بدون PoW (غير موصى به)")
160
  else:
161
- logger.info("WASM file found successfully.")
162
 
163
  logger.info("=" * 60)
164
 
165
 
166
  # ============================================================
167
- # Authentication with token refresh
168
  # ============================================================
169
 
170
  account_queue = ACCOUNTS.copy()
171
  random.shuffle(account_queue)
172
 
 
 
 
173
  def login_deepseek_via_account(account):
174
- """تسجيل الدخول مع تسجيل تفصيلي للاستجابة"""
175
  email = account.get("email", "").strip()
176
  password = account.get("password", "").strip()
177
 
178
  if not email or not password:
179
- logger.error("الحساب يفتقر إلى البريد الإلكتروني أو كلمة المرور")
180
- raise HTTPException(
181
- status_code=400,
182
- detail="الحساب يجب أن يحتوي على email و password"
183
- )
184
 
185
  payload = {
186
  "email": email,
@@ -189,7 +179,7 @@ def login_deepseek_via_account(account):
189
  "os": "android",
190
  }
191
 
192
- logger.info(f"محاولة تسجيل الدخول للحساب: {email}")
193
 
194
  try:
195
  resp = requests.post(
@@ -203,25 +193,23 @@ def login_deepseek_via_account(account):
203
  try:
204
  data = resp.json()
205
  except Exception as e:
206
- logger.error(f"فشل تحليل استجابة JSON: {e}")
207
- logger.error(f"نص الاستجابة: {resp.text[:500]}")
208
- raise HTTPException(status_code=500, detail="استجابة غير صالحة من الخادم")
209
 
210
  logger.info(f"استجابة تسجيل الدخول: code={data.get('code')}, msg={data.get('msg', 'N/A')}")
211
 
212
  if resp.status_code != 200 or data.get("code") != 0:
213
- error_msg = data.get("msg", "خطأ غير معروف في تسجيل الدخول")
214
- logger.error(f"فشل تسجيل الدخول للحساب {email}: {error_msg}")
215
  raise HTTPException(status_code=401, detail=f"فشل تسجيل الدخول: {error_msg}")
216
 
217
  user_data = data.get("data", {}).get("biz_data", {}).get("user")
218
  if not user_data:
219
- logger.error(f"استجابة تسجيل الدخول غير مكتملة: {data}")
220
- raise HTTPException(status_code=500, detail="استجابة تسجيل الدخول غير مكتملة")
221
 
222
  new_token = user_data.get("token")
223
  if not new_token:
224
- logger.error(f"لم يتم العثور على token في الاستجابة: {user_data}")
225
  raise HTTPException(status_code=500, detail="لم يتم الحصول على token")
226
 
227
  account["token"] = new_token
@@ -230,47 +218,39 @@ def login_deepseek_via_account(account):
230
 
231
  except HTTPException:
232
  raise
233
- except requests.RequestException as e:
234
- logger.error(f"خطأ في طلب تسجيل الدخول للحساب {email}: {e}")
235
- raise HTTPException(status_code=500, detail=f"خطأ في الاتصال: {str(e)}")
236
  except Exception as e:
237
- logger.error(f"خطأ غير متوقع في تسجيل الدخول للحساب {email}: {e}")
238
- raise HTTPException(status_code=500, detail=f"خطأ داخلي: {str(e)}")
239
 
240
- def refresh_token_for_account(account):
241
- """تحديث التوكن لحساب معين"""
242
- try:
243
- logger.info(f"تحديث التوكن للحساب: {account.get('email')}")
244
- return login_deepseek_via_account(account)
245
- except Exception as e:
246
- logger.error(f"فشل تحديث التوكن للحساب {account.get('email')}: {e}")
247
- raise
248
 
249
  def get_valid_token():
250
- """الحصول على token صالح مع إعادة المحاولة"""
251
  if not account_queue:
252
- logger.error("لا توجد حسابات متاحة")
253
- raise HTTPException(
254
- status_code=500,
255
- detail="لا توجد حسابات متاحة. تأكد من تعيين DEEPSEEK_EMAIL و DEEPSEEK_PASSWORD."
256
- )
257
 
 
258
  account = account_queue.pop(0)
259
  email = account.get("email", "unknown")
260
 
261
- # محاولة تسجيل الدخول للحصول على token جديد دائماً
 
 
 
 
 
 
 
 
262
  try:
263
- logger.info(f"تسجيل الدخول للحصول على token جديد: {email}")
264
  token = login_deepseek_via_account(account)
 
265
  account_queue.append(account)
266
  return token, account
267
  except Exception as e:
268
- logger.error(f"فشل الحصول على token من الحساب {email}: {e}")
269
  if account_queue:
270
- logger.info("محاولة استخدام الحساب التالي...")
271
  return get_valid_token()
272
- else:
273
- raise HTTPException(status_code=500, detail="فشل تسجيل الدخول لجميع الحسابات")
274
 
275
  def get_deepseek_token():
276
  try:
@@ -278,30 +258,28 @@ def get_deepseek_token():
278
  except HTTPException:
279
  raise
280
  except Exception as e:
281
- logger.error(f"خطأ غير متوقع في get_deepseek_token: {e}")
282
- raise HTTPException(status_code=500, detail="خطأ داخلي في المصادقة")
 
283
 
284
  def determine_mode_and_token(request: Request):
285
  try:
286
  token, account = get_deepseek_token()
287
  request.state.deepseek_token = token
288
  request.state.account = account
289
- request.state.use_config_token = False
290
- logger.info(f"تم تعيين التوكن للطلب بنجاح")
291
- except HTTPException as e:
292
- logger.error(f"فشل تعيين التوكن: {e.detail}")
293
- raise
294
  except Exception as e:
295
- logger.error(f"خطأ غير متوقع في determine_mode_and_token: {e}")
296
- raise HTTPException(status_code=500, detail="خطأ في المصادقة")
 
297
 
298
  def determine_claude_mode_and_token(request: Request):
299
  determine_mode_and_token(request)
300
 
 
301
  def get_auth_headers(request: Request):
302
  token = getattr(request.state, "deepseek_token", None)
303
  if not token:
304
- logger.warning("لم يتم العثور على token في الطلب، محاولة الحصول على واحد جديد")
305
  token, _ = get_deepseek_token()
306
  request.state.deepseek_token = token
307
  return {
@@ -311,7 +289,7 @@ def get_auth_headers(request: Request):
311
 
312
 
313
  # ============================================================
314
- # Utility functions (unchanged)
315
  # ============================================================
316
 
317
  def safe_json_response_error(status_code: int, message: str):
@@ -515,7 +493,7 @@ Do not write explanations before or after the JSON.
515
 
516
 
517
  # ============================================================
518
- # DeepSeek completion helpers
519
  # ============================================================
520
 
521
  def call_completion_endpoint(payload, headers, max_attempts=3):
@@ -539,9 +517,13 @@ def call_completion_endpoint(payload, headers, max_attempts=3):
539
  time.sleep(1)
540
  return None
541
 
542
- def create_session(request: Request, max_attempts=3):
 
 
 
543
  for attempt in range(max_attempts):
544
  headers = get_auth_headers(request)
 
545
  try:
546
  response = requests.post(
547
  DEEPSEEK_CREATE_SESSION_URL,
@@ -550,84 +532,71 @@ def create_session(request: Request, max_attempts=3):
550
  impersonate="safari15_3",
551
  timeout=30
552
  )
 
553
  try:
554
  data = response.json()
555
- logger.info(f"Create session response: code={data.get('code')}, msg={data.get('msg', 'N/A')}")
556
-
557
- # طباعة الاستجابة كاملة للتصحيح
558
- if data.get('code') == 0:
559
- biz_data = data.get('data', {}).get('biz_data', {})
560
- logger.info(f"biz_data: {biz_data}")
561
  except Exception as e:
562
- logger.error(f"فشل تحليل استجابة إنشاء الجلسة: {e}")
563
  data = {}
564
 
565
  if response.status_code == 200 and data.get("code") == 0:
566
- # محاولة الحصول على session_id من عدة أماكن
567
- session_id = (
568
- data.get("data", {}).get("biz_data", {}).get("id") or
569
- data.get("data", {}).get("id") or
570
- data.get("session_id")
571
- )
572
- response.close()
573
  if session_id:
 
574
  logger.info(f"تم إنشاء الجلسة: {session_id}")
575
  return session_id
576
  else:
577
- logger.warning(f"Create session: session_id missing in response. Data: {data}")
578
- # محاولة إعادة تسجيل الدخول للحصول على token جديد
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  account = getattr(request.state, "account", None)
580
  if account:
581
  try:
582
- logger.info("محاولة تحديث التوكن...")
583
- new_token = refresh_token_for_account(account)
584
- request.state.deepseek_token = new_token
585
  continue
586
  except Exception as e:
587
  logger.error(f"فشل تحديث التوكن: {e}")
588
- elif response.status_code == 401:
589
- logger.warning("Create session: 401 Unauthorized, refreshing token...")
590
- account = getattr(request.state, "account", None)
591
- if account:
592
- try:
593
- new_token = refresh_token_for_account(account)
594
- request.state.deepseek_token = new_token
595
- continue
596
- except Exception as e:
597
- logger.error(f"فشل تحديث التوكن: {e}")
598
- try:
599
- token, new_account = get_deepseek_token()
600
- request.state.deepseek_token = token
601
- request.state.account = new_account
602
- continue
603
- except Exception as e2:
604
- logger.error(f"فشل الحصول على حساب آخر: {e2}")
605
- else:
606
- try:
607
- token, new_account = get_deepseek_token()
608
- request.state.deepseek_token = token
609
- request.state.account = new_account
610
- continue
611
- except Exception as e:
612
- logger.error(f"فشل الحصول على حساب: {e}")
613
- else:
614
- error_msg = data.get("msg", f"HTTP {response.status_code}")
615
- logger.warning(f"Create session failed: {error_msg}")
616
- response.close()
617
  except Exception as exc:
618
  logger.warning(f"Create session error: {exc}")
 
619
  if attempt < max_attempts - 1:
620
  time.sleep(1)
 
621
  return None
622
 
623
  def compute_pow_answer(algorithm, challenge_str, salt, difficulty, expire_at, signature, target_path, wasm_path):
624
  if algorithm != "DeepSeekHashV1":
625
  raise ValueError(f"Unsupported PoW algorithm: {algorithm}")
626
  if not os.path.isfile(wasm_path):
627
- logger.error(f"WASM file not found: {wasm_path}")
628
- # محاولة تحميل الملف
629
  if download_wasm_file():
630
- logger.info("تم تحميل WASM بنجاح")
631
  else:
632
  raise FileNotFoundError(f"WASM file not found: {wasm_path}")
633
 
@@ -677,7 +646,7 @@ def compute_pow_answer(algorithm, challenge_str, salt, difficulty, expire_at, si
677
  finally:
678
  add_to_stack(store, 16)
679
 
680
- def get_pow_response(request: Request, max_attempts=3):
681
  for attempt in range(max_attempts):
682
  headers = get_auth_headers(request)
683
  try:
@@ -724,34 +693,18 @@ def get_pow_response(request: Request, max_attempts=3):
724
  response.close()
725
  logger.info("تم الحصول على PoW بنجاح")
726
  return encoded
727
- elif response.status_code == 401:
728
  logger.warning("PoW: 401 Unauthorized, refreshing token...")
729
  account = getattr(request.state, "account", None)
730
  if account:
731
  try:
732
- new_token = refresh_token_for_account(account)
733
- request.state.deepseek_token = new_token
734
- continue
735
- except Exception as e:
736
- logger.error(f"فشل تحديث التوكن: {e}")
737
- try:
738
- token, new_account = get_deepseek_token()
739
- request.state.deepseek_token = token
740
- request.state.account = new_account
741
- continue
742
- except Exception as e2:
743
- logger.error(f"فشل الحصول على حساب آخر: {e2}")
744
- else:
745
- try:
746
- token, new_account = get_deepseek_token()
747
  request.state.deepseek_token = token
748
- request.state.account = new_account
749
  continue
750
  except Exception as e:
751
- logger.error(f"فشل الحصول على حساب: {e}")
752
  else:
753
- logger.warning("PoW request failed: HTTP=%s code=%s msg=%s",
754
- response.status_code, data.get("code"), data.get("msg"))
755
  response.close()
756
  except Exception as exc:
757
  logger.error("PoW error: %s", exc)
@@ -771,9 +724,7 @@ def delete_session(request: Request, session_id: str):
771
  timeout=5
772
  )
773
  if response.status_code == 200:
774
- logger.info("Deleted DeepSeek session: %s", session_id)
775
- else:
776
- logger.warning("Delete session failed: HTTP %s", response.status_code)
777
  response.close()
778
  except Exception as exc:
779
  logger.warning("Delete session error: %s", exc)
@@ -831,7 +782,7 @@ def parse_deepseek_stream(response, on_text=None, on_thinking=None):
831
 
832
 
833
  # ============================================================
834
- # Rest of the endpoints (same as before)
835
  # ============================================================
836
 
837
  @app.get("/v1/models")
@@ -844,6 +795,7 @@ async def list_models():
844
  ]
845
  return {"object": "list", "data": models}
846
 
 
847
  @app.post("/v1/chat/completions")
848
  async def chat_completions(request: Request):
849
  try:
@@ -873,10 +825,12 @@ async def chat_completions(request: Request):
873
 
874
  final_prompt = messages_prepare(messages)
875
 
 
876
  session_id = create_session(request)
877
  if not session_id:
878
  return safe_json_response_error(401, "Unable to create DeepSeek session.")
879
 
 
880
  pow_response = get_pow_response(request)
881
  if not pow_response:
882
  delete_session(request, session_id)
@@ -903,6 +857,7 @@ async def chat_completions(request: Request):
903
  created = int(time.time())
904
  completion_id = f"chatcmpl-{session_id}"
905
 
 
906
  if req_data.get("stream", False):
907
  def stream_generator():
908
  final_text = []
@@ -1022,6 +977,7 @@ async def chat_completions(request: Request):
1022
  headers={"Cache-Control": "no-cache", "Connection": "keep-alive", "X-Accel-Buffering": "no"}
1023
  )
1024
 
 
1025
  final_text = []
1026
  final_thinking = []
1027
  parse_deepseek_stream(deepseek_response, on_text=final_text.append, on_thinking=final_thinking.append)
@@ -1061,7 +1017,7 @@ async def chat_completions(request: Request):
1061
 
1062
 
1063
  # ============================================================
1064
- # Claude endpoints (shortened - same as before)
1065
  # ============================================================
1066
 
1067
  @app.get("/anthropic/v1/models")
 
31
  DEEPSEEK_PASSWORD = os.getenv("DEEPSEEK_PASSWORD", "").strip()
32
  DEEPSEEK_EMAIL_2 = os.getenv("DEEPSEEK_EMAIL_2", "").strip()
33
  DEEPSEEK_PASSWORD_2 = os.getenv("DEEPSEEK_PASSWORD_2", "").strip()
 
 
34
 
35
  ACCOUNTS = []
36
  if DEEPSEEK_EMAIL and DEEPSEEK_PASSWORD:
37
  ACCOUNTS.append({
38
  "email": DEEPSEEK_EMAIL,
39
  "password": DEEPSEEK_PASSWORD,
40
+ "token": ""
41
  })
42
  if DEEPSEEK_EMAIL_2 and DEEPSEEK_PASSWORD_2:
43
  ACCOUNTS.append({
44
  "email": DEEPSEEK_EMAIL_2,
45
  "password": DEEPSEEK_PASSWORD_2,
46
+ "token": ""
47
  })
48
 
49
  WASM_PATH = os.getenv("WASM_PATH", "./sha3_wasm_bg.7b9ca65ddd.wasm")
 
52
  KEEP_ALIVE_TIMEOUT = 5
53
  CLAUDE_DEFAULT_MODEL = "claude-sonnet-4-20250514"
54
 
 
55
  # ============================================================
56
  # Logging
57
  # ============================================================
 
88
  # ============================================================
89
 
90
  def download_wasm_file():
 
91
  try:
92
  logger.info(f"محاولة تحميل WASM من: {WASM_URL}")
93
  urllib.request.urlretrieve(WASM_URL, WASM_PATH)
94
  if os.path.isfile(WASM_PATH):
95
  logger.info(f"تم تحميل WASM بنجاح إلى: {os.path.abspath(WASM_PATH)}")
96
  return True
97
+ return False
 
 
98
  except Exception as e:
99
  logger.error(f"فشل تحميل WASM: {e}")
100
  return False
 
126
 
127
 
128
  # ============================================================
129
+ # Startup event
130
  # ============================================================
131
 
132
  @app.on_event("startup")
 
141
  for acc in ACCOUNTS:
142
  logger.info(" - %s", acc.get("email"))
143
  else:
144
+ logger.warning("No accounts configured.")
145
 
 
146
  if not os.path.isfile(WASM_PATH):
147
+ logger.warning("WASM file missing, attempting download...")
 
148
  if download_wasm_file():
149
+ logger.info("WASM downloaded successfully")
150
  else:
151
+ logger.critical("Failed to download WASM file")
152
  else:
153
+ logger.info("WASM file found.")
154
 
155
  logger.info("=" * 60)
156
 
157
 
158
  # ============================================================
159
+ # Authentication
160
  # ============================================================
161
 
162
  account_queue = ACCOUNTS.copy()
163
  random.shuffle(account_queue)
164
 
165
+ # تخزين التوكنات مؤقتاً
166
+ token_cache = {}
167
+
168
  def login_deepseek_via_account(account):
 
169
  email = account.get("email", "").strip()
170
  password = account.get("password", "").strip()
171
 
172
  if not email or not password:
173
+ raise HTTPException(status_code=400, detail="الحساب يجب أن يحتوي على email و password")
 
 
 
 
174
 
175
  payload = {
176
  "email": email,
 
179
  "os": "android",
180
  }
181
 
182
+ logger.info(f"تسجيل الدخول للحساب: {email}")
183
 
184
  try:
185
  resp = requests.post(
 
193
  try:
194
  data = resp.json()
195
  except Exception as e:
196
+ logger.error(f"فشل تحليل الاستجابة: {e}")
197
+ raise HTTPException(status_code=500, detail="استجابة غير صالحة")
 
198
 
199
  logger.info(f"استجابة تسجيل الدخول: code={data.get('code')}, msg={data.get('msg', 'N/A')}")
200
 
201
  if resp.status_code != 200 or data.get("code") != 0:
202
+ error_msg = data.get("msg", "خطأ غير معروف")
203
+ logger.error(f"فشل تسجيل الدخول: {error_msg}")
204
  raise HTTPException(status_code=401, detail=f"فشل تسجيل الدخول: {error_msg}")
205
 
206
  user_data = data.get("data", {}).get("biz_data", {}).get("user")
207
  if not user_data:
208
+ logger.error(f"استجابة غير مكتملة: {data}")
209
+ raise HTTPException(status_code=500, detail="استجابة غير مكتملة")
210
 
211
  new_token = user_data.get("token")
212
  if not new_token:
 
213
  raise HTTPException(status_code=500, detail="لم يتم الحصول على token")
214
 
215
  account["token"] = new_token
 
218
 
219
  except HTTPException:
220
  raise
 
 
 
221
  except Exception as e:
222
+ logger.error(f"خطأ في تسجيل الدخول: {e}")
223
+ raise HTTPException(status_code=500, detail=str(e))
224
 
 
 
 
 
 
 
 
 
225
 
226
  def get_valid_token():
 
227
  if not account_queue:
228
+ raise HTTPException(status_code=500, detail="لا توجد حسابات متاحة")
 
 
 
 
229
 
230
+ # نأخذ حساب من القائمة
231
  account = account_queue.pop(0)
232
  email = account.get("email", "unknown")
233
 
234
+ # التحقق من التخزين المؤقت
235
+ if email in token_cache and token_cache[email].get("token"):
236
+ logger.info(f"استخدام token مخزن للحساب: {email}")
237
+ token = token_cache[email]["token"]
238
+ account["token"] = token
239
+ account_queue.append(account)
240
+ return token, account
241
+
242
+ # تسجيل الدخول
243
  try:
 
244
  token = login_deepseek_via_account(account)
245
+ token_cache[email] = {"token": token, "timestamp": time.time()}
246
  account_queue.append(account)
247
  return token, account
248
  except Exception as e:
249
+ logger.error(f"فشل تسجيل الدخول للحساب {email}: {e}")
250
  if account_queue:
 
251
  return get_valid_token()
252
+ raise
253
+
254
 
255
  def get_deepseek_token():
256
  try:
 
258
  except HTTPException:
259
  raise
260
  except Exception as e:
261
+ logger.error(f"خطأ في get_deepseek_token: {e}")
262
+ raise HTTPException(status_code=500, detail="خطأ في المصادقة")
263
+
264
 
265
  def determine_mode_and_token(request: Request):
266
  try:
267
  token, account = get_deepseek_token()
268
  request.state.deepseek_token = token
269
  request.state.account = account
270
+ logger.info(f"تم تعيين التوكن للطلب")
 
 
 
 
271
  except Exception as e:
272
+ logger.error(f"فشل تعيين التوكن: {e}")
273
+ raise
274
+
275
 
276
  def determine_claude_mode_and_token(request: Request):
277
  determine_mode_and_token(request)
278
 
279
+
280
  def get_auth_headers(request: Request):
281
  token = getattr(request.state, "deepseek_token", None)
282
  if not token:
 
283
  token, _ = get_deepseek_token()
284
  request.state.deepseek_token = token
285
  return {
 
289
 
290
 
291
  # ============================================================
292
+ # Utility functions
293
  # ============================================================
294
 
295
  def safe_json_response_error(status_code: int, message: str):
 
493
 
494
 
495
  # ============================================================
496
+ # DeepSeek completion helpers - FIXED session_id extraction
497
  # ============================================================
498
 
499
  def call_completion_endpoint(payload, headers, max_attempts=3):
 
517
  time.sleep(1)
518
  return None
519
 
520
+ def create_session(request: Request, max_attempts=2):
521
+ """
522
+ إنشاء جلسة DeepSeek مع إصلاح قراءة session_id
523
+ """
524
  for attempt in range(max_attempts):
525
  headers = get_auth_headers(request)
526
+
527
  try:
528
  response = requests.post(
529
  DEEPSEEK_CREATE_SESSION_URL,
 
532
  impersonate="safari15_3",
533
  timeout=30
534
  )
535
+
536
  try:
537
  data = response.json()
538
+ logger.info(f"Create session response: code={data.get('code')}")
 
 
 
 
 
539
  except Exception as e:
540
+ logger.error(f"فشل تحليل الاستجابة: {e}")
541
  data = {}
542
 
543
  if response.status_code == 200 and data.get("code") == 0:
544
+ # ============================================================
545
+ # إصلاح قراءة session_id من المكان الصحيح
546
+ # ============================================================
547
+ biz_data = data.get("data", {}).get("biz_data", {})
548
+ chat_session = biz_data.get("chat_session", {})
549
+ session_id = chat_session.get("id")
550
+
551
  if session_id:
552
+ response.close()
553
  logger.info(f"تم إنشاء الجلسة: {session_id}")
554
  return session_id
555
  else:
556
+ logger.warning(f"session_id غير موجود في الاستجابة")
557
+ # نحاول مرة واحدة فقط إعادة تسجيل الدخول
558
+ if attempt == 0:
559
+ logger.info("محاولة تسجيل الدخول مرة أخرى...")
560
+ account = getattr(request.state, "account", None)
561
+ if account:
562
+ try:
563
+ # تحديث التوكن
564
+ token = login_deepseek_via_account(account)
565
+ request.state.deepseek_token = token
566
+ continue
567
+ except Exception as e:
568
+ logger.error(f"فشل تحديث التوكن: {e}")
569
+ continue
570
+ else:
571
+ error_msg = data.get("msg", f"HTTP {response.status_code}")
572
+ logger.warning(f"Create session failed: {error_msg}")
573
+ response.close()
574
+
575
+ # في حالة 401، نحاول تحديث التوكن
576
+ if response.status_code == 401 and attempt == 0:
577
  account = getattr(request.state, "account", None)
578
  if account:
579
  try:
580
+ token = login_deepseek_via_account(account)
581
+ request.state.deepseek_token = token
 
582
  continue
583
  except Exception as e:
584
  logger.error(f"فشل تحديث التوكن: {e}")
585
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  except Exception as exc:
587
  logger.warning(f"Create session error: {exc}")
588
+
589
  if attempt < max_attempts - 1:
590
  time.sleep(1)
591
+
592
  return None
593
 
594
  def compute_pow_answer(algorithm, challenge_str, salt, difficulty, expire_at, signature, target_path, wasm_path):
595
  if algorithm != "DeepSeekHashV1":
596
  raise ValueError(f"Unsupported PoW algorithm: {algorithm}")
597
  if not os.path.isfile(wasm_path):
 
 
598
  if download_wasm_file():
599
+ logger.info("WASM downloaded successfully")
600
  else:
601
  raise FileNotFoundError(f"WASM file not found: {wasm_path}")
602
 
 
646
  finally:
647
  add_to_stack(store, 16)
648
 
649
+ def get_pow_response(request: Request, max_attempts=2):
650
  for attempt in range(max_attempts):
651
  headers = get_auth_headers(request)
652
  try:
 
693
  response.close()
694
  logger.info("تم الحصول على PoW بنجاح")
695
  return encoded
696
+ elif response.status_code == 401 and attempt == 0:
697
  logger.warning("PoW: 401 Unauthorized, refreshing token...")
698
  account = getattr(request.state, "account", None)
699
  if account:
700
  try:
701
+ token = login_deepseek_via_account(account)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
  request.state.deepseek_token = token
 
703
  continue
704
  except Exception as e:
705
+ logger.error(f"فشل تحديث التوكن: {e}")
706
  else:
707
+ logger.warning("PoW request failed: HTTP=%s code=%s", response.status_code, data.get("code"))
 
708
  response.close()
709
  except Exception as exc:
710
  logger.error("PoW error: %s", exc)
 
724
  timeout=5
725
  )
726
  if response.status_code == 200:
727
+ logger.info("Deleted session: %s", session_id)
 
 
728
  response.close()
729
  except Exception as exc:
730
  logger.warning("Delete session error: %s", exc)
 
782
 
783
 
784
  # ============================================================
785
+ # Endpoints (unchanged)
786
  # ============================================================
787
 
788
  @app.get("/v1/models")
 
795
  ]
796
  return {"object": "list", "data": models}
797
 
798
+
799
  @app.post("/v1/chat/completions")
800
  async def chat_completions(request: Request):
801
  try:
 
825
 
826
  final_prompt = messages_prepare(messages)
827
 
828
+ # إنشاء الجلسة
829
  session_id = create_session(request)
830
  if not session_id:
831
  return safe_json_response_error(401, "Unable to create DeepSeek session.")
832
 
833
+ # الحصول على PoW
834
  pow_response = get_pow_response(request)
835
  if not pow_response:
836
  delete_session(request, session_id)
 
857
  created = int(time.time())
858
  completion_id = f"chatcmpl-{session_id}"
859
 
860
+ # Streaming
861
  if req_data.get("stream", False):
862
  def stream_generator():
863
  final_text = []
 
977
  headers={"Cache-Control": "no-cache", "Connection": "keep-alive", "X-Accel-Buffering": "no"}
978
  )
979
 
980
+ # Non-streaming
981
  final_text = []
982
  final_thinking = []
983
  parse_deepseek_stream(deepseek_response, on_text=final_text.append, on_thinking=final_thinking.append)
 
1017
 
1018
 
1019
  # ============================================================
1020
+ # Claude endpoints (shortened)
1021
  # ============================================================
1022
 
1023
  @app.get("/anthropic/v1/models")