dragg2 commited on
Commit
54ef0e9
·
verified ·
1 Parent(s): 92e7d88

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -37
app.py CHANGED
@@ -104,9 +104,12 @@ CONFIG = {
104
  "PROXY": os.environ.get("PROXY") or None
105
  },
106
  "SERVER": {
 
 
107
  "PORT": int(os.environ.get("PORT", 5200))
108
  },
109
  "RETRY": {
 
110
  "MAX_ATTEMPTS": 2
111
  },
112
  "SHOW_THINKING": os.environ.get("SHOW_THINKING") == "true",
@@ -250,13 +253,15 @@ class AuthTokenManager:
250
  except Exception as error:
251
  logger.error(f"重置校对token请求次数时发生错误: {str(error)}", "TokenManager")
252
  return False
253
- def get_next_token_for_model(self, model_id):
254
  normalized_model = self.normalize_model_name(model_id)
255
 
256
  if normalized_model not in self.token_model_map or not self.token_model_map[normalized_model]:
257
  return None
258
 
259
  token_entry = self.token_model_map[normalized_model][0]
 
 
260
 
261
  if token_entry:
262
  if token_entry["StartCallTime"] is None:
@@ -409,6 +414,14 @@ class AuthTokenManager:
409
  for entry in model_tokens:
410
  all_tokens.add(entry["token"])
411
  return list(all_tokens)
 
 
 
 
 
 
 
 
412
 
413
  def get_token_status_map(self):
414
  return self.token_status_map
@@ -433,8 +446,8 @@ class Utils:
433
  return '\n\n'.join(formatted_results)
434
 
435
  @staticmethod
436
- def create_auth_headers(model):
437
- return token_manager.get_next_token_for_model(model)
438
 
439
  @staticmethod
440
  def get_proxy_options():
@@ -443,6 +456,7 @@ class Utils:
443
 
444
  if proxy:
445
  logger.info(f"使用代理: {proxy}", "Server")
 
446
  if proxy.startswith("socks5://"):
447
  proxy_options["proxy"] = proxy
448
 
@@ -452,8 +466,7 @@ class Utils:
452
  username, password = auth_part.split(':')
453
  proxy_options["proxy_auth"] = (username, password)
454
  else:
455
- proxy_options["proxies"] = {"https": proxy, "http": proxy}
456
- print(proxy_options)
457
  return proxy_options
458
 
459
  class GrokApiClient:
@@ -482,7 +495,40 @@ class GrokApiClient:
482
  "mimeType": mime_type,
483
  "fileName": file_name
484
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
 
 
 
 
 
 
 
 
486
  def upload_base64_image(self, base64_data, url):
487
  try:
488
  if 'data:image' in base64_data:
@@ -510,7 +556,7 @@ class GrokApiClient:
510
  url,
511
  headers={
512
  **DEFAULT_HEADERS,
513
- "Cookie": CONFIG["API"]["SIGNATURE_COOKIE"]
514
  },
515
  json=upload_data,
516
  impersonate="chrome133a",
@@ -546,6 +592,9 @@ class GrokApiClient:
546
  messages = ''
547
  last_role = None
548
  last_content = ''
 
 
 
549
  search = request["model"] in ['grok-2-search', 'grok-3-search']
550
 
551
  # 移除<think>标签及其内容和base64图片
@@ -595,7 +644,9 @@ class GrokApiClient:
595
 
596
 
597
  text_content = process_content(current.get("content", ""))
598
-
 
 
599
  if text_content or (is_last_message and file_attachments):
600
  if role == last_role and text_content:
601
  last_content += '\n' + text_content
@@ -604,6 +655,14 @@ class GrokApiClient:
604
  messages += f"{role.upper()}: {text_content or '[图片]'}\n"
605
  last_content = text_content
606
  last_role = role
 
 
 
 
 
 
 
 
607
 
608
  return {
609
  "temporary": CONFIG["API"].get("IS_TEMP_CONVERSATION", False),
@@ -724,7 +783,7 @@ def handle_image_response(image_url):
724
  f"https://assets.grok.com/{image_url}",
725
  headers={
726
  **DEFAULT_HEADERS,
727
- "Cookie": CONFIG["API"]["SIGNATURE_COOKIE"]
728
  },
729
  impersonate="chrome120",
730
  **proxy_options
@@ -940,7 +999,20 @@ def add_token():
940
  except Exception as error:
941
  logger.error(str(error), "Server")
942
  return jsonify({"error": '添加sso令牌失败'}), 500
943
-
 
 
 
 
 
 
 
 
 
 
 
 
 
944
  @app.route('/delete/token', methods=['POST'])
945
  def delete_token():
946
  auth_token = request.headers.get('Authorization', '').replace('Bearer ', '')
@@ -974,6 +1046,7 @@ def get_models():
974
 
975
  @app.route('/v1/chat/completions', methods=['POST'])
976
  def chat_completions():
 
977
  try:
978
  auth_token = request.headers.get('Authorization',
979
  '').replace('Bearer ', '')
@@ -993,61 +1066,57 @@ def chat_completions():
993
  retry_count = 0
994
  grok_client = GrokApiClient(model)
995
  request_payload = grok_client.prepare_chat_request(data)
996
- response_status_code = 500
997
 
998
  while retry_count < CONFIG["RETRY"]["MAX_ATTEMPTS"]:
999
  retry_count += 1
1000
- CONFIG["API"]["SIGNATURE_COOKIE"] = Utils.create_auth_headers(
1001
- model)
1002
 
1003
  if not CONFIG["API"]["SIGNATURE_COOKIE"]:
1004
  raise ValueError('该模型无可用令牌')
1005
 
1006
  logger.info(
1007
- f"当前令牌: {json.dumps(CONFIG['API']['SIGNATURE_COOKIE'], indent=2)}",
1008
- "Server")
1009
  logger.info(
1010
- f"当前可用模型的全部可用数量: {json.dumps(token_manager.get_remaining_token_request_capacity(), indent=2)}",
1011
- "Server")
1012
-
 
 
 
 
1013
  try:
1014
  proxy_options = Utils.get_proxy_options()
1015
  response = curl_requests.post(
1016
  f"{CONFIG['API']['BASE_URL']}/rest/app-chat/conversations/new",
1017
  headers={
1018
- **DEFAULT_HEADERS, "Cookie":
1019
- CONFIG["API"]["SIGNATURE_COOKIE"]
1020
  },
1021
  data=json.dumps(request_payload),
1022
  impersonate="chrome133a",
1023
  stream=True,
1024
  **proxy_options)
 
1025
  if response.status_code == 200:
1026
  response_status_code = 200
1027
  logger.info("请求成功", "Server")
1028
- logger.info(
1029
- f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}",
1030
- "Server")
1031
 
1032
  try:
1033
  if stream:
1034
  return Response(stream_with_context(
1035
- handle_stream_response(response, model)),
1036
- content_type='text/event-stream')
1037
  else:
1038
- content = handle_non_stream_response(
1039
- response, model)
1040
  return jsonify(
1041
- MessageProcessor.create_chat_response(
1042
- content, model))
1043
 
1044
  except Exception as error:
1045
  logger.error(str(error), "Server")
1046
  if CONFIG["API"]["IS_CUSTOM_SSO"]:
1047
  raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
1048
-
1049
- token_manager.remove_token_from_model(
1050
- model, CONFIG["API"]["SIGNATURE_COOKIE"])
1051
  if token_manager.get_token_count_for_model(model) == 0:
1052
  raise ValueError(f"{model} 次数已达上限,请切换其他模型或者重新对话")
1053
  elif response.status_code == 403:
@@ -1055,7 +1124,7 @@ def chat_completions():
1055
  token_manager.reduce_token_request_count(model,1)#重置去除当前因为错误未成功请求的次数,确保不会因为错误未成功请求的次数导致次数上限
1056
  if token_manager.get_token_count_for_model(model) == 0:
1057
  raise ValueError(f"{model} 次数已达上限,请切换其他模型或者重新对话")
1058
- raise ValueError(f"IP暂时被封黑无法破盾,请稍后重试或者更换ip")
1059
  elif response.status_code == 429:
1060
  response_status_code = 429
1061
  token_manager.reduce_token_request_count(model,1)
@@ -1071,10 +1140,8 @@ def chat_completions():
1071
  if CONFIG["API"]["IS_CUSTOM_SSO"]:
1072
  raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
1073
 
1074
- logger.error(f"令牌异常错误状态!status: {response.status_code}",
1075
- "Server")
1076
- token_manager.remove_token_from_model(
1077
- model, CONFIG["API"]["SIGNATURE_COOKIE"])
1078
  logger.info(
1079
  f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}",
1080
  "Server")
@@ -1085,7 +1152,7 @@ def chat_completions():
1085
  raise
1086
  continue
1087
  if response_status_code == 403:
1088
- raise ValueError('IP暂时被封黑无法破盾,请稍后重试或者更换ip')
1089
  elif response_status_code == 500:
1090
  raise ValueError('当前模型所有令牌暂无可用,请稍后重试')
1091
 
 
104
  "PROXY": os.environ.get("PROXY") or None
105
  },
106
  "SERVER": {
107
+ "COOKIE": None,
108
+ "CF_CLEARANCE":os.environ.get("CF_CLEARANCE") or None,
109
  "PORT": int(os.environ.get("PORT", 5200))
110
  },
111
  "RETRY": {
112
+ "RETRYSWITCH": False,
113
  "MAX_ATTEMPTS": 2
114
  },
115
  "SHOW_THINKING": os.environ.get("SHOW_THINKING") == "true",
 
253
  except Exception as error:
254
  logger.error(f"重置校对token请求次数时发生错误: {str(error)}", "TokenManager")
255
  return False
256
+ def get_next_token_for_model(self, model_id, is_return=False):
257
  normalized_model = self.normalize_model_name(model_id)
258
 
259
  if normalized_model not in self.token_model_map or not self.token_model_map[normalized_model]:
260
  return None
261
 
262
  token_entry = self.token_model_map[normalized_model][0]
263
+ if is_return:
264
+ return token_entry["token"]
265
 
266
  if token_entry:
267
  if token_entry["StartCallTime"] is None:
 
414
  for entry in model_tokens:
415
  all_tokens.add(entry["token"])
416
  return list(all_tokens)
417
+ def get_current_token(self, model_id):
418
+ normalized_model = self.normalize_model_name(model_id)
419
+
420
+ if normalized_model not in self.token_model_map or not self.token_model_map[normalized_model]:
421
+ return None
422
+
423
+ token_entry = self.token_model_map[normalized_model][0]
424
+ return token_entry["token"]
425
 
426
  def get_token_status_map(self):
427
  return self.token_status_map
 
446
  return '\n\n'.join(formatted_results)
447
 
448
  @staticmethod
449
+ def create_auth_headers(model, is_return=False):
450
+ return token_manager.get_next_token_for_model(model, is_return)
451
 
452
  @staticmethod
453
  def get_proxy_options():
 
456
 
457
  if proxy:
458
  logger.info(f"使用代理: {proxy}", "Server")
459
+
460
  if proxy.startswith("socks5://"):
461
  proxy_options["proxy"] = proxy
462
 
 
466
  username, password = auth_part.split(':')
467
  proxy_options["proxy_auth"] = (username, password)
468
  else:
469
+ proxy_options["proxies"] = {"https": proxy, "http": proxy}
 
470
  return proxy_options
471
 
472
  class GrokApiClient:
 
495
  "mimeType": mime_type,
496
  "fileName": file_name
497
  }
498
+ def upload_base64_file(self, message, model):
499
+ try:
500
+ message_base64 = base64.b64encode(message.encode('utf-8')).decode('utf-8')
501
+ upload_data = {
502
+ "fileName": "message.txt",
503
+ "fileMimeType": "text/plain",
504
+ "content": message_base64
505
+ }
506
+
507
+ logger.info("发送文字文件请求", "Server")
508
+ cookie = f"{Utils.create_auth_headers(model, True)};{CONFIG['SERVER']['CF_CLEARANCE']}"
509
+ proxy_options = Utils.get_proxy_options()
510
+ response = curl_requests.post(
511
+ "https://grok.com/rest/app-chat/upload-file",
512
+ headers={
513
+ **DEFAULT_HEADERS,
514
+ "Cookie":cookie
515
+ },
516
+ json=upload_data,
517
+ impersonate="chrome133a",
518
+ **proxy_options
519
+ )
520
+
521
+ if response.status_code != 200:
522
+ logger.error(f"上传文件失败,状态码:{response.status_code}", "Server")
523
+ raise Exception(f"上传文件失败,状态码:{response.status_code}")
524
 
525
+ result = response.json()
526
+ logger.info(f"上传文件成功: {result}", "Server")
527
+ return result.get("fileMetadataId", "")
528
+
529
+ except Exception as error:
530
+ logger.error(str(error), "Server")
531
+ raise Exception(f"上传文件失败,状态码:{response.status_code}")
532
  def upload_base64_image(self, base64_data, url):
533
  try:
534
  if 'data:image' in base64_data:
 
556
  url,
557
  headers={
558
  **DEFAULT_HEADERS,
559
+ "Cookie":CONFIG["SERVER"]['COOKIE']
560
  },
561
  json=upload_data,
562
  impersonate="chrome133a",
 
592
  messages = ''
593
  last_role = None
594
  last_content = ''
595
+ message_length = 0
596
+ convert_to_file = False
597
+ last_message_content = ''
598
  search = request["model"] in ['grok-2-search', 'grok-3-search']
599
 
600
  # 移除<think>标签及其内容和base64图片
 
644
 
645
 
646
  text_content = process_content(current.get("content", ""))
647
+ if is_last_message and convert_to_file:
648
+ last_message_content = f"{role.upper()}: {text_content or '[图片]'}\n"
649
+ continue
650
  if text_content or (is_last_message and file_attachments):
651
  if role == last_role and text_content:
652
  last_content += '\n' + text_content
 
655
  messages += f"{role.upper()}: {text_content or '[图片]'}\n"
656
  last_content = text_content
657
  last_role = role
658
+ message_length += len(messages)
659
+ if message_length >= 40000:
660
+ convert_to_file = True
661
+ if convert_to_file:
662
+ file_id = self.upload_base64_file(messages, request["model"])
663
+ if file_id:
664
+ file_attachments.insert(0, file_id)
665
+ messages = last_message_content.strip()
666
 
667
  return {
668
  "temporary": CONFIG["API"].get("IS_TEMP_CONVERSATION", False),
 
783
  f"https://assets.grok.com/{image_url}",
784
  headers={
785
  **DEFAULT_HEADERS,
786
+ "Cookie":CONFIG["SERVER"]['COOKIE']
787
  },
788
  impersonate="chrome120",
789
  **proxy_options
 
999
  except Exception as error:
1000
  logger.error(str(error), "Server")
1001
  return jsonify({"error": '添加sso令牌失败'}), 500
1002
+
1003
+ @app.route('/set/cf_clearance', methods=['POST'])
1004
+ def setCf_clearance():
1005
+ auth_token = request.headers.get('Authorization', '').replace('Bearer ', '')
1006
+ if auth_token != CONFIG["API"]["API_KEY"]:
1007
+ return jsonify({"error": 'Unauthorized'}), 401
1008
+ try:
1009
+ cf_clearance = request.json.get('cf_clearance')
1010
+ CONFIG["SERVER"]['CF_CLEARANCE'] = cf_clearance
1011
+ return jsonify({"message": '设置cf_clearance成功'}), 200
1012
+ except Exception as error:
1013
+ logger.error(str(error), "Server")
1014
+ return jsonify({"error": '设置cf_clearance失败'}), 500
1015
+
1016
  @app.route('/delete/token', methods=['POST'])
1017
  def delete_token():
1018
  auth_token = request.headers.get('Authorization', '').replace('Bearer ', '')
 
1046
 
1047
  @app.route('/v1/chat/completions', methods=['POST'])
1048
  def chat_completions():
1049
+ response_status_code = 500
1050
  try:
1051
  auth_token = request.headers.get('Authorization',
1052
  '').replace('Bearer ', '')
 
1066
  retry_count = 0
1067
  grok_client = GrokApiClient(model)
1068
  request_payload = grok_client.prepare_chat_request(data)
1069
+
1070
 
1071
  while retry_count < CONFIG["RETRY"]["MAX_ATTEMPTS"]:
1072
  retry_count += 1
1073
+ CONFIG["API"]["SIGNATURE_COOKIE"] = Utils.create_auth_headers(model)
 
1074
 
1075
  if not CONFIG["API"]["SIGNATURE_COOKIE"]:
1076
  raise ValueError('该模型无可用令牌')
1077
 
1078
  logger.info(
1079
+ f"当前令牌: {json.dumps(CONFIG['API']['SIGNATURE_COOKIE'], indent=2)}","Server")
 
1080
  logger.info(
1081
+ f"当前可用模型的全部可用数量: {json.dumps(token_manager.get_remaining_token_request_capacity(), indent=2)}","Server")
1082
+
1083
+ if CONFIG['SERVER']['CF_CLEARANCE']:
1084
+ CONFIG["SERVER"]['COOKIE'] = f"{CONFIG['API']['SIGNATURE_COOKIE']};{CONFIG['SERVER']['CF_CLEARANCE']}"
1085
+ else:
1086
+ CONFIG["SERVER"]['COOKIE'] = CONFIG['API']['SIGNATURE_COOKIE']
1087
+ logger.info(json.dumps(request_payload,indent=2),"Server")
1088
  try:
1089
  proxy_options = Utils.get_proxy_options()
1090
  response = curl_requests.post(
1091
  f"{CONFIG['API']['BASE_URL']}/rest/app-chat/conversations/new",
1092
  headers={
1093
+ **DEFAULT_HEADERS,
1094
+ "Cookie":CONFIG["SERVER"]['COOKIE']
1095
  },
1096
  data=json.dumps(request_payload),
1097
  impersonate="chrome133a",
1098
  stream=True,
1099
  **proxy_options)
1100
+ logger.info(CONFIG["SERVER"]['COOKIE'],"Server")
1101
  if response.status_code == 200:
1102
  response_status_code = 200
1103
  logger.info("请求成功", "Server")
1104
+ logger.info(f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}","Server")
 
 
1105
 
1106
  try:
1107
  if stream:
1108
  return Response(stream_with_context(
1109
+ handle_stream_response(response, model)),content_type='text/event-stream')
 
1110
  else:
1111
+ content = handle_non_stream_response(response, model)
 
1112
  return jsonify(
1113
+ MessageProcessor.create_chat_response(content, model))
 
1114
 
1115
  except Exception as error:
1116
  logger.error(str(error), "Server")
1117
  if CONFIG["API"]["IS_CUSTOM_SSO"]:
1118
  raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
1119
+ token_manager.remove_token_from_model(model, CONFIG["API"]["SIGNATURE_COOKIE"])
 
 
1120
  if token_manager.get_token_count_for_model(model) == 0:
1121
  raise ValueError(f"{model} 次数已达上限,请切换其他模型或者重新对话")
1122
  elif response.status_code == 403:
 
1124
  token_manager.reduce_token_request_count(model,1)#重置去除当前因为错误未成功请求的次数,确保不会因为错误未成功请求的次数导致次数上限
1125
  if token_manager.get_token_count_for_model(model) == 0:
1126
  raise ValueError(f"{model} 次数已达上限,请切换其他模型或者重新对话")
1127
+ raise ValueError(f"IP暂时被封无法破盾,请稍后重试或者更换ip")
1128
  elif response.status_code == 429:
1129
  response_status_code = 429
1130
  token_manager.reduce_token_request_count(model,1)
 
1140
  if CONFIG["API"]["IS_CUSTOM_SSO"]:
1141
  raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
1142
 
1143
+ logger.error(f"令牌异常错误状态!status: {response.status_code}","Server")
1144
+ token_manager.remove_token_from_model(model, CONFIG["API"]["SIGNATURE_COOKIE"])
 
 
1145
  logger.info(
1146
  f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}",
1147
  "Server")
 
1152
  raise
1153
  continue
1154
  if response_status_code == 403:
1155
+ raise ValueError('IP暂时被封无法破盾,请稍后重试或者更换ip')
1156
  elif response_status_code == 500:
1157
  raise ValueError('当前模型所有令牌暂无可用,请稍后重试')
1158