Update app.py
Browse files
app.py
CHANGED
|
@@ -5,13 +5,19 @@ import time
|
|
| 5 |
import base64
|
| 6 |
import sys
|
| 7 |
import inspect
|
|
|
|
| 8 |
from loguru import logger
|
|
|
|
| 9 |
|
| 10 |
import requests
|
| 11 |
-
from flask import Flask, request, Response, jsonify, stream_with_context
|
| 12 |
from curl_cffi import requests as curl_requests
|
| 13 |
from werkzeug.middleware.proxy_fix import ProxyFix
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
class Logger:
|
| 17 |
def __init__(self, level="INFO", colorize=True, format=None):
|
|
@@ -93,30 +99,34 @@ CONFIG = {
|
|
| 93 |
"grok-3-reasoning": "grok-3"
|
| 94 |
},
|
| 95 |
"API": {
|
| 96 |
-
"IS_TEMP_CONVERSATION": os.
|
| 97 |
-
"IS_CUSTOM_SSO": os.
|
| 98 |
"BASE_URL": "https://grok.com",
|
| 99 |
-
"API_KEY": os.
|
| 100 |
"SIGNATURE_COOKIE": None,
|
| 101 |
-
"PICGO_KEY": os.
|
| 102 |
-
"TUMY_KEY": os.
|
| 103 |
"RETRY_TIME": 1000,
|
| 104 |
-
"PROXY": os.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
},
|
| 106 |
"SERVER": {
|
| 107 |
"COOKIE": None,
|
| 108 |
-
"CF_CLEARANCE":os.
|
| 109 |
-
"PORT": int(os.
|
| 110 |
},
|
| 111 |
"RETRY": {
|
| 112 |
"RETRYSWITCH": False,
|
| 113 |
"MAX_ATTEMPTS": 2
|
| 114 |
},
|
| 115 |
-
"SHOW_THINKING": os.
|
| 116 |
"IS_THINKING": False,
|
| 117 |
"IS_IMG_GEN": False,
|
| 118 |
"IS_IMG_GEN2": False,
|
| 119 |
-
"ISSHOW_SEARCH_RESULTS": os.
|
| 120 |
}
|
| 121 |
|
| 122 |
|
|
@@ -515,6 +525,7 @@ class GrokApiClient:
|
|
| 515 |
},
|
| 516 |
json=upload_data,
|
| 517 |
impersonate="chrome133a",
|
|
|
|
| 518 |
**proxy_options
|
| 519 |
)
|
| 520 |
|
|
@@ -560,6 +571,7 @@ class GrokApiClient:
|
|
| 560 |
},
|
| 561 |
json=upload_data,
|
| 562 |
impersonate="chrome133a",
|
|
|
|
| 563 |
**proxy_options
|
| 564 |
)
|
| 565 |
|
|
@@ -587,7 +599,6 @@ class GrokApiClient:
|
|
| 587 |
if last_message["role"] != 'user':
|
| 588 |
raise ValueError('此模型最后一条消息必须是用户消息!')
|
| 589 |
todo_messages = [last_message]
|
| 590 |
-
|
| 591 |
file_attachments = []
|
| 592 |
messages = ''
|
| 593 |
last_role = None
|
|
@@ -658,12 +669,17 @@ class GrokApiClient:
|
|
| 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),
|
| 669 |
"modelName": self.model_id,
|
|
@@ -785,7 +801,7 @@ def handle_image_response(image_url):
|
|
| 785 |
**DEFAULT_HEADERS,
|
| 786 |
"Cookie":CONFIG["SERVER"]['COOKIE']
|
| 787 |
},
|
| 788 |
-
impersonate="
|
| 789 |
**proxy_options
|
| 790 |
)
|
| 791 |
|
|
@@ -951,7 +967,7 @@ def handle_stream_response(response, model):
|
|
| 951 |
return generate()
|
| 952 |
|
| 953 |
def initialization():
|
| 954 |
-
sso_array = os.
|
| 955 |
logger.info("开始加载令牌", "Server")
|
| 956 |
for sso in sso_array:
|
| 957 |
if sso:
|
|
@@ -968,11 +984,76 @@ logger.info("初始化完成", "Server")
|
|
| 968 |
|
| 969 |
app = Flask(__name__)
|
| 970 |
app.wsgi_app = ProxyFix(app.wsgi_app)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 971 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 972 |
|
| 973 |
-
@app.before_request
|
| 974 |
-
def log_request_info():
|
| 975 |
-
logger.info(f"{request.method} {request.path}", "Request")
|
| 976 |
|
| 977 |
@app.route('/get/tokens', methods=['GET'])
|
| 978 |
def get_tokens():
|
|
@@ -981,7 +1062,6 @@ def get_tokens():
|
|
| 981 |
return jsonify({"error": '自定义的SSO令牌模式无法获取轮询sso令牌状态'}), 403
|
| 982 |
elif auth_token != CONFIG["API"]["API_KEY"]:
|
| 983 |
return jsonify({"error": 'Unauthorized'}), 401
|
| 984 |
-
|
| 985 |
return jsonify(token_manager.get_token_status_map())
|
| 986 |
|
| 987 |
@app.route('/add/token', methods=['POST'])
|
|
@@ -1093,8 +1173,9 @@ def chat_completions():
|
|
| 1093 |
**DEFAULT_HEADERS,
|
| 1094 |
"Cookie":CONFIG["SERVER"]['COOKIE']
|
| 1095 |
},
|
| 1096 |
-
|
| 1097 |
impersonate="chrome133a",
|
|
|
|
| 1098 |
stream=True,
|
| 1099 |
**proxy_options)
|
| 1100 |
logger.info(CONFIG["SERVER"]['COOKIE'],"Server")
|
|
|
|
| 5 |
import base64
|
| 6 |
import sys
|
| 7 |
import inspect
|
| 8 |
+
import secrets
|
| 9 |
from loguru import logger
|
| 10 |
+
from dotenv import load_dotenv
|
| 11 |
|
| 12 |
import requests
|
| 13 |
+
from flask import Flask, request, Response, jsonify, stream_with_context, render_template, redirect, session
|
| 14 |
from curl_cffi import requests as curl_requests
|
| 15 |
from werkzeug.middleware.proxy_fix import ProxyFix
|
| 16 |
|
| 17 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 18 |
+
env_path = os.path.join(current_dir, '.env')
|
| 19 |
+
|
| 20 |
+
load_dotenv(env_path)
|
| 21 |
|
| 22 |
class Logger:
|
| 23 |
def __init__(self, level="INFO", colorize=True, format=None):
|
|
|
|
| 99 |
"grok-3-reasoning": "grok-3"
|
| 100 |
},
|
| 101 |
"API": {
|
| 102 |
+
"IS_TEMP_CONVERSATION": os.getenv("IS_TEMP_CONVERSATION", "true").lower() == "true",
|
| 103 |
+
"IS_CUSTOM_SSO": os.getenv("IS_CUSTOM_SSO", "false").lower() == "true",
|
| 104 |
"BASE_URL": "https://grok.com",
|
| 105 |
+
"API_KEY": os.getenv("API_KEY", "sk-123456"),
|
| 106 |
"SIGNATURE_COOKIE": None,
|
| 107 |
+
"PICGO_KEY": os.getenv("PICGO_KEY") or None,
|
| 108 |
+
"TUMY_KEY": os.getenv("TUMY_KEY") or None,
|
| 109 |
"RETRY_TIME": 1000,
|
| 110 |
+
"PROXY": os.getenv("PROXY") or None
|
| 111 |
+
},
|
| 112 |
+
"ADMIN": {
|
| 113 |
+
"MANAGER_SWITCH": os.getenv("MANAGER_SWITCH") or None,
|
| 114 |
+
"PASSWORD": os.getenv("ADMINPASSWORD") or None
|
| 115 |
},
|
| 116 |
"SERVER": {
|
| 117 |
"COOKIE": None,
|
| 118 |
+
"CF_CLEARANCE":os.getenv("CF_CLEARANCE") or None,
|
| 119 |
+
"PORT": int(os.getenv("PORT", 5200))
|
| 120 |
},
|
| 121 |
"RETRY": {
|
| 122 |
"RETRYSWITCH": False,
|
| 123 |
"MAX_ATTEMPTS": 2
|
| 124 |
},
|
| 125 |
+
"SHOW_THINKING": os.getenv("SHOW_THINKING") == "true",
|
| 126 |
"IS_THINKING": False,
|
| 127 |
"IS_IMG_GEN": False,
|
| 128 |
"IS_IMG_GEN2": False,
|
| 129 |
+
"ISSHOW_SEARCH_RESULTS": os.getenv("ISSHOW_SEARCH_RESULTS", "true").lower() == "true"
|
| 130 |
}
|
| 131 |
|
| 132 |
|
|
|
|
| 525 |
},
|
| 526 |
json=upload_data,
|
| 527 |
impersonate="chrome133a",
|
| 528 |
+
verify=False,
|
| 529 |
**proxy_options
|
| 530 |
)
|
| 531 |
|
|
|
|
| 571 |
},
|
| 572 |
json=upload_data,
|
| 573 |
impersonate="chrome133a",
|
| 574 |
+
verify=False,
|
| 575 |
**proxy_options
|
| 576 |
)
|
| 577 |
|
|
|
|
| 599 |
if last_message["role"] != 'user':
|
| 600 |
raise ValueError('此模型最后一条消息必须是用户消息!')
|
| 601 |
todo_messages = [last_message]
|
|
|
|
| 602 |
file_attachments = []
|
| 603 |
messages = ''
|
| 604 |
last_role = None
|
|
|
|
| 669 |
message_length += len(messages)
|
| 670 |
if message_length >= 40000:
|
| 671 |
convert_to_file = True
|
| 672 |
+
|
| 673 |
if convert_to_file:
|
| 674 |
file_id = self.upload_base64_file(messages, request["model"])
|
| 675 |
if file_id:
|
| 676 |
file_attachments.insert(0, file_id)
|
| 677 |
messages = last_message_content.strip()
|
| 678 |
+
if messages.strip() == '':
|
| 679 |
+
if convert_to_file:
|
| 680 |
+
messages = '基于txt文件内容进行回复:'
|
| 681 |
+
else:
|
| 682 |
+
raise ValueError('消息内容为空!')
|
| 683 |
return {
|
| 684 |
"temporary": CONFIG["API"].get("IS_TEMP_CONVERSATION", False),
|
| 685 |
"modelName": self.model_id,
|
|
|
|
| 801 |
**DEFAULT_HEADERS,
|
| 802 |
"Cookie":CONFIG["SERVER"]['COOKIE']
|
| 803 |
},
|
| 804 |
+
impersonate="chrome133a",
|
| 805 |
**proxy_options
|
| 806 |
)
|
| 807 |
|
|
|
|
| 967 |
return generate()
|
| 968 |
|
| 969 |
def initialization():
|
| 970 |
+
sso_array = os.getenv("SSO", "").split(',')
|
| 971 |
logger.info("开始加载令牌", "Server")
|
| 972 |
for sso in sso_array:
|
| 973 |
if sso:
|
|
|
|
| 984 |
|
| 985 |
app = Flask(__name__)
|
| 986 |
app.wsgi_app = ProxyFix(app.wsgi_app)
|
| 987 |
+
app.secret_key = os.getenv('FLASK_SECRET_KEY') or secrets.token_hex(16)
|
| 988 |
+
app.json.sort_keys = False
|
| 989 |
+
|
| 990 |
+
@app.route('/manager/login', methods=['GET', 'POST'])
|
| 991 |
+
def manager_login():
|
| 992 |
+
if CONFIG["ADMIN"]["MANAGER_SWITCH"]:
|
| 993 |
+
if request.method == 'POST':
|
| 994 |
+
password = request.form.get('password')
|
| 995 |
+
if password == CONFIG["ADMIN"]["PASSWORD"]:
|
| 996 |
+
session['is_logged_in'] = True
|
| 997 |
+
return redirect('/manager')
|
| 998 |
+
return render_template('login.html', error=True)
|
| 999 |
+
return render_template('login.html', error=False)
|
| 1000 |
+
else:
|
| 1001 |
+
return redirect('/')
|
| 1002 |
+
|
| 1003 |
+
def check_auth():
|
| 1004 |
+
return session.get('is_logged_in', False)
|
| 1005 |
+
|
| 1006 |
+
@app.route('/manager')
|
| 1007 |
+
def manager():
|
| 1008 |
+
if not check_auth():
|
| 1009 |
+
return redirect('/manager/login')
|
| 1010 |
+
return render_template('manager.html')
|
| 1011 |
+
|
| 1012 |
+
@app.route('/manager/api/get')
|
| 1013 |
+
def get_manager_tokens():
|
| 1014 |
+
if not check_auth():
|
| 1015 |
+
return jsonify({"error": "Unauthorized"}), 401
|
| 1016 |
+
return jsonify(token_manager.get_token_status_map())
|
| 1017 |
|
| 1018 |
+
@app.route('/manager/api/add', methods=['POST'])
|
| 1019 |
+
def add_manager_token():
|
| 1020 |
+
if not check_auth():
|
| 1021 |
+
return jsonify({"error": "Unauthorized"}), 401
|
| 1022 |
+
try:
|
| 1023 |
+
sso = request.json.get('sso')
|
| 1024 |
+
if not sso:
|
| 1025 |
+
return jsonify({"error": "SSO token is required"}), 400
|
| 1026 |
+
token_manager.add_token(f"sso-rw={sso};sso={sso}")
|
| 1027 |
+
return jsonify({"success": True})
|
| 1028 |
+
except Exception as e:
|
| 1029 |
+
return jsonify({"error": str(e)}), 500
|
| 1030 |
+
|
| 1031 |
+
@app.route('/manager/api/delete', methods=['POST'])
|
| 1032 |
+
def delete_manager_token():
|
| 1033 |
+
if not check_auth():
|
| 1034 |
+
return jsonify({"error": "Unauthorized"}), 401
|
| 1035 |
+
try:
|
| 1036 |
+
sso = request.json.get('sso')
|
| 1037 |
+
if not sso:
|
| 1038 |
+
return jsonify({"error": "SSO token is required"}), 400
|
| 1039 |
+
token_manager.delete_token(f"sso-rw={sso};sso={sso}")
|
| 1040 |
+
return jsonify({"success": True})
|
| 1041 |
+
except Exception as e:
|
| 1042 |
+
return jsonify({"error": str(e)}), 500
|
| 1043 |
+
|
| 1044 |
+
@app.route('/manager/api/cf_clearance', methods=['POST'])
|
| 1045 |
+
def setCf_Manager_clearance():
|
| 1046 |
+
if not check_auth():
|
| 1047 |
+
return jsonify({"error": "Unauthorized"}), 401
|
| 1048 |
+
try:
|
| 1049 |
+
cf_clearance = request.json.get('cf_clearance')
|
| 1050 |
+
if not cf_clearance:
|
| 1051 |
+
return jsonify({"error": "cf_clearance is required"}), 400
|
| 1052 |
+
CONFIG["SERVER"]['CF_CLEARANCE'] = cf_clearance
|
| 1053 |
+
return jsonify({"success": True})
|
| 1054 |
+
except Exception as e:
|
| 1055 |
+
return jsonify({"error": str(e)}), 500
|
| 1056 |
|
|
|
|
|
|
|
|
|
|
| 1057 |
|
| 1058 |
@app.route('/get/tokens', methods=['GET'])
|
| 1059 |
def get_tokens():
|
|
|
|
| 1062 |
return jsonify({"error": '自定义的SSO令牌模式无法获取轮询sso令牌状态'}), 403
|
| 1063 |
elif auth_token != CONFIG["API"]["API_KEY"]:
|
| 1064 |
return jsonify({"error": 'Unauthorized'}), 401
|
|
|
|
| 1065 |
return jsonify(token_manager.get_token_status_map())
|
| 1066 |
|
| 1067 |
@app.route('/add/token', methods=['POST'])
|
|
|
|
| 1173 |
**DEFAULT_HEADERS,
|
| 1174 |
"Cookie":CONFIG["SERVER"]['COOKIE']
|
| 1175 |
},
|
| 1176 |
+
json=request_payload,
|
| 1177 |
impersonate="chrome133a",
|
| 1178 |
+
verify=False,
|
| 1179 |
stream=True,
|
| 1180 |
**proxy_options)
|
| 1181 |
logger.info(CONFIG["SERVER"]['COOKIE'],"Server")
|