Spaces:
Paused
Paused
Upload 2 files
Browse files- Dockerfile +1 -1
- app.py +104 -91
Dockerfile
CHANGED
|
@@ -23,4 +23,4 @@ ENV PYTHONUNBUFFERED=1
|
|
| 23 |
EXPOSE 3000
|
| 24 |
|
| 25 |
# 使用 gunicorn 作为生产级 WSGI 服务器
|
| 26 |
-
CMD ["gunicorn", "--bind", "0.0.0.0:3000", "--workers", "4", "app:app"]
|
|
|
|
| 23 |
EXPOSE 3000
|
| 24 |
|
| 25 |
# 使用 gunicorn 作为生产级 WSGI 服务器
|
| 26 |
+
CMD ["gunicorn", "--bind", "0.0.0.0:3000", "--workers", "4", "--timeout", "120", "app:app"]
|
app.py
CHANGED
|
@@ -107,7 +107,7 @@ def create_custom_session():
|
|
| 107 |
return session
|
| 108 |
|
| 109 |
# 添加速率限制相关的常量
|
| 110 |
-
AUTH_RETRY_DELAY = 60 #
|
| 111 |
AUTH_BACKOFF_FACTOR = 2 # 退避因子
|
| 112 |
AUTH_MAX_RETRIES = 3 # 最大重试次数
|
| 113 |
AUTH_CHECK_INTERVAL = 300 # 健康检查间隔(秒)
|
|
@@ -308,32 +308,35 @@ class MultiAuthManager:
|
|
| 308 |
self.auth_managers = [AuthManager(email, password) for email, password in credentials]
|
| 309 |
self.current_index = 0
|
| 310 |
self.last_success_index = 0 # 记录上一次成功的账号索引
|
| 311 |
-
self.
|
|
|
|
| 312 |
|
| 313 |
def get_next_auth_manager(self, model):
|
| 314 |
"""改进的账号选择逻辑,从上次成功的账号开始尝试"""
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
|
|
|
|
|
|
| 337 |
|
| 338 |
def ensure_valid_token(self, model):
|
| 339 |
auth_manager = self.get_next_auth_manager(model)
|
|
@@ -828,6 +831,7 @@ def make_request(payload, auth_manager, model_id):
|
|
| 828 |
global multi_auth_manager
|
| 829 |
max_retries = 3
|
| 830 |
retry_delay = 1
|
|
|
|
| 831 |
|
| 832 |
logger.info(f"尝试发送请求,模型:{model_id}")
|
| 833 |
|
|
@@ -848,77 +852,86 @@ def make_request(payload, auth_manager, model_id):
|
|
| 848 |
tried_accounts = set()
|
| 849 |
|
| 850 |
while True: # 持续尝试,直到成功或确定所有账号都不可用
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
-
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
| 860 |
-
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
# 如果这个账号已经尝试过,跳过
|
| 868 |
-
if auth_manager._email in tried_accounts:
|
| 869 |
-
continue
|
| 870 |
-
|
| 871 |
-
tried_accounts.add(auth_manager._email)
|
| 872 |
-
logger.info(f"尝试使用账号 {auth_manager._email}")
|
| 873 |
-
|
| 874 |
-
for attempt in range(max_retries):
|
| 875 |
-
try:
|
| 876 |
-
url = get_notdiamond_url()
|
| 877 |
-
headers = get_notdiamond_headers(auth_manager)
|
| 878 |
-
|
| 879 |
-
# 使用 session 发送请求
|
| 880 |
-
session = create_custom_session()
|
| 881 |
-
response = session.post(
|
| 882 |
-
url,
|
| 883 |
-
headers=headers,
|
| 884 |
-
json=payload,
|
| 885 |
-
stream=True,
|
| 886 |
-
timeout=30 # 添加超时设置
|
| 887 |
-
)
|
| 888 |
-
|
| 889 |
-
if response.status_code == 200:
|
| 890 |
-
logger.info(f"请求成功,使用账号 {auth_manager._email}")
|
| 891 |
-
return response
|
| 892 |
-
|
| 893 |
-
# 处理不同的错误状态码
|
| 894 |
-
if response.status_code == 401: # Unauthorized
|
| 895 |
-
logger.warning(f"Token expired for account {auth_manager._email}")
|
| 896 |
-
if auth_manager.ensure_valid_token():
|
| 897 |
-
continue
|
| 898 |
-
break
|
| 899 |
|
| 900 |
-
|
| 901 |
-
|
| 902 |
-
|
| 903 |
-
break
|
| 904 |
|
| 905 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 906 |
if attempt < max_retries - 1:
|
| 907 |
time.sleep(retry_delay * (attempt + 1))
|
| 908 |
-
|
| 909 |
-
|
| 910 |
-
|
| 911 |
-
|
| 912 |
-
|
| 913 |
-
|
| 914 |
-
|
| 915 |
-
|
| 916 |
-
|
| 917 |
-
|
| 918 |
-
|
| 919 |
-
|
| 920 |
-
|
| 921 |
-
|
| 922 |
|
| 923 |
raise Exception("无法完成请求,所有可用账号都已尝试")
|
| 924 |
|
|
|
|
| 107 |
return session
|
| 108 |
|
| 109 |
# 添加速率限制相关的常量
|
| 110 |
+
AUTH_RETRY_DELAY = 60 # 认证试延迟(秒)
|
| 111 |
AUTH_BACKOFF_FACTOR = 2 # 退避因子
|
| 112 |
AUTH_MAX_RETRIES = 3 # 最大重试次数
|
| 113 |
AUTH_CHECK_INTERVAL = 300 # 健康检查间隔(秒)
|
|
|
|
| 308 |
self.auth_managers = [AuthManager(email, password) for email, password in credentials]
|
| 309 |
self.current_index = 0
|
| 310 |
self.last_success_index = 0 # 记录上一次成功的账号索引
|
| 311 |
+
self._last_rotation_date = None # 使用None作为初始值
|
| 312 |
+
self._lock = threading.Lock() # 添加线程锁
|
| 313 |
|
| 314 |
def get_next_auth_manager(self, model):
|
| 315 |
"""改进的账号选择逻辑,从上次成功的账号开始尝试"""
|
| 316 |
+
with self._lock: # 使用线程锁保护共享状态
|
| 317 |
+
try:
|
| 318 |
+
current_date = datetime.now().date()
|
| 319 |
+
|
| 320 |
+
# 初始化或检查日期变更
|
| 321 |
+
if self._last_rotation_date is None or current_date > self._last_rotation_date:
|
| 322 |
+
self.current_index = 0
|
| 323 |
+
self.last_success_index = 0
|
| 324 |
+
self._last_rotation_date = current_date
|
| 325 |
+
# 重置所有账号的模型状态
|
| 326 |
+
for auth_manager in self.auth_managers:
|
| 327 |
+
auth_manager.reset_model_status()
|
| 328 |
+
return self.auth_managers[0] if self.auth_managers else None
|
| 329 |
+
|
| 330 |
+
# 从上次成功的账号开始尝试
|
| 331 |
+
self.current_index = self.last_success_index
|
| 332 |
+
if 0 <= self.current_index < len(self.auth_managers):
|
| 333 |
+
auth_manager = self.auth_managers[self.current_index]
|
| 334 |
+
if auth_manager.is_model_available(model) and auth_manager._should_attempt_auth():
|
| 335 |
+
return auth_manager
|
| 336 |
+
return None
|
| 337 |
+
except Exception as e:
|
| 338 |
+
logger.error(f"Error in get_next_auth_manager: {str(e)}")
|
| 339 |
+
return None
|
| 340 |
|
| 341 |
def ensure_valid_token(self, model):
|
| 342 |
auth_manager = self.get_next_auth_manager(model)
|
|
|
|
| 831 |
global multi_auth_manager
|
| 832 |
max_retries = 3
|
| 833 |
retry_delay = 1
|
| 834 |
+
request_timeout = 10 # 减少单次请求超时时间
|
| 835 |
|
| 836 |
logger.info(f"尝试发送请求,模型:{model_id}")
|
| 837 |
|
|
|
|
| 852 |
tried_accounts = set()
|
| 853 |
|
| 854 |
while True: # 持续尝试,直到成功或确定所有账号都不可用
|
| 855 |
+
try:
|
| 856 |
+
auth_manager = multi_auth_manager.get_next_auth_manager(model_id)
|
| 857 |
+
if not auth_manager:
|
| 858 |
+
# 检查是否所有账号都已尝试
|
| 859 |
+
if len(tried_accounts) >= len(multi_auth_manager.auth_managers):
|
| 860 |
+
logger.error("所有账号都已尝试且不可用")
|
| 861 |
+
# 尝试注册新账号
|
| 862 |
+
successful_accounts = register_bot.register_and_verify(5)
|
| 863 |
+
if successful_accounts:
|
| 864 |
+
credentials = [(account['email'], account['password']) for account in successful_accounts]
|
| 865 |
+
multi_auth_manager = MultiAuthManager(credentials)
|
| 866 |
+
tried_accounts.clear() # 清空已尝试账号列表
|
| 867 |
+
continue # 继续尝试新注册的账号
|
| 868 |
+
else:
|
| 869 |
+
raise Exception("所有账号均不可用,且注册新账号失败")
|
| 870 |
+
continue # 如果还有未尝试的账号,继续循环
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 871 |
|
| 872 |
+
# 如果这个账号已经尝试过,跳过
|
| 873 |
+
if auth_manager._email in tried_accounts:
|
| 874 |
+
continue
|
|
|
|
| 875 |
|
| 876 |
+
tried_accounts.add(auth_manager._email)
|
| 877 |
+
logger.info(f"尝试使用账号 {auth_manager._email}")
|
| 878 |
+
|
| 879 |
+
for attempt in range(max_retries):
|
| 880 |
+
try:
|
| 881 |
+
url = get_notdiamond_url()
|
| 882 |
+
headers = get_notdiamond_headers(auth_manager)
|
| 883 |
+
|
| 884 |
+
# 使用 session 发送请求
|
| 885 |
+
session = create_custom_session()
|
| 886 |
+
response = session.post(
|
| 887 |
+
url,
|
| 888 |
+
headers=headers,
|
| 889 |
+
json=payload,
|
| 890 |
+
stream=True,
|
| 891 |
+
timeout=request_timeout
|
| 892 |
+
)
|
| 893 |
+
|
| 894 |
+
if response.status_code == 200:
|
| 895 |
+
logger.info(f"请求成功,使用账号 {auth_manager._email}")
|
| 896 |
+
return response
|
| 897 |
+
|
| 898 |
+
# 处理不同的错误状态码
|
| 899 |
+
if response.status_code == 401: # Unauthorized
|
| 900 |
+
logger.warning(f"Token expired for account {auth_manager._email}")
|
| 901 |
+
if auth_manager.ensure_valid_token():
|
| 902 |
+
continue
|
| 903 |
+
break
|
| 904 |
+
|
| 905 |
+
if response.status_code == 403: # Forbidden
|
| 906 |
+
logger.warning(f"Model {model_id} usage limit reached for account {auth_manager._email}")
|
| 907 |
+
auth_manager.set_model_unavailable(model_id)
|
| 908 |
+
break
|
| 909 |
+
|
| 910 |
+
if response.status_code >= 500: # Server error
|
| 911 |
+
if attempt < max_retries - 1:
|
| 912 |
+
time.sleep(retry_delay * (attempt + 1))
|
| 913 |
+
continue
|
| 914 |
+
|
| 915 |
+
logger.error(f"Request failed with status {response.status_code}")
|
| 916 |
+
|
| 917 |
+
except requests.Timeout:
|
| 918 |
+
logger.warning(f"Request timeout for account {auth_manager._email}, attempt {attempt + 1}")
|
| 919 |
if attempt < max_retries - 1:
|
| 920 |
time.sleep(retry_delay * (attempt + 1))
|
| 921 |
+
continue
|
| 922 |
+
except requests.RequestException as e:
|
| 923 |
+
logger.error(f"Request error: {str(e)}")
|
| 924 |
+
if attempt < max_retries - 1:
|
| 925 |
+
time.sleep(retry_delay * (attempt + 1))
|
| 926 |
+
continue
|
| 927 |
+
except Exception as e:
|
| 928 |
+
logger.error(f"Unexpected error: {str(e)}")
|
| 929 |
+
if attempt < max_retries - 1:
|
| 930 |
+
time.sleep(retry_delay * (attempt + 1))
|
| 931 |
+
continue
|
| 932 |
+
except Exception as e:
|
| 933 |
+
logger.error(f"Error in main request loop: {str(e)}")
|
| 934 |
+
time.sleep(retry_delay)
|
| 935 |
|
| 936 |
raise Exception("无法完成请求,所有可用账号都已尝试")
|
| 937 |
|