Spaces:
Paused
Paused
Update src/key_manager.py
Browse files- src/key_manager.py +30 -10
src/key_manager.py
CHANGED
|
@@ -30,7 +30,9 @@ class KeyManager:
|
|
| 30 |
api_keys_str = os.getenv("API_KEYS", "")
|
| 31 |
if api_keys_str:
|
| 32 |
try:
|
|
|
|
| 33 |
env_data = json.loads(api_keys_str)
|
|
|
|
| 34 |
self._process_keys_data(env_data)
|
| 35 |
if len(self.keys) > 0:
|
| 36 |
logger.info(f"已从环境变量加载 {len(self.keys)} 个密钥")
|
|
@@ -40,13 +42,14 @@ class KeyManager:
|
|
| 40 |
except json.JSONDecodeError as e:
|
| 41 |
logger.error(f"解析环境变量API keys失败: {str(e)}")
|
| 42 |
|
| 43 |
-
|
| 44 |
if not keys_loaded:
|
| 45 |
try:
|
| 46 |
if os.path.exists(self.storage_file):
|
| 47 |
logger.info(f"尝试从文件加载密钥: {self.storage_file}")
|
| 48 |
with open(self.storage_file, 'r', encoding='utf-8') as f:
|
| 49 |
data = json.load(f)
|
|
|
|
| 50 |
keys_before = len(self.keys)
|
| 51 |
self._process_keys_data(data)
|
| 52 |
keys_loaded = len(self.keys) > keys_before
|
|
@@ -58,6 +61,8 @@ class KeyManager:
|
|
| 58 |
|
| 59 |
if len(self.keys) == 0:
|
| 60 |
logger.warning("未能从环境变量或文件加载任何密钥")
|
|
|
|
|
|
|
| 61 |
|
| 62 |
|
| 63 |
def _process_keys_data(self, data):
|
|
@@ -66,11 +71,12 @@ class KeyManager:
|
|
| 66 |
if isinstance(data, list):
|
| 67 |
# 旧版格式:直接是密钥列表
|
| 68 |
raw_keys = data
|
| 69 |
-
|
| 70 |
-
|
| 71 |
|
| 72 |
# 为每个密钥创建完整的记录
|
| 73 |
for key_info in raw_keys:
|
|
|
|
| 74 |
if isinstance(key_info, dict):
|
| 75 |
key_value = key_info.get("key")
|
| 76 |
if not key_value:
|
|
@@ -96,10 +102,11 @@ class KeyManager:
|
|
| 96 |
"notes": key_info.get("notes")
|
| 97 |
}
|
| 98 |
|
| 99 |
-
|
|
|
|
| 100 |
|
| 101 |
# 初始化使用统计
|
| 102 |
-
|
| 103 |
"total_requests": 0,
|
| 104 |
"successful_requests": 0,
|
| 105 |
"failed_requests": 0,
|
|
@@ -109,7 +116,7 @@ class KeyManager:
|
|
| 109 |
elif isinstance(key_info, str):
|
| 110 |
# 如果是字符串,直接作为密钥值
|
| 111 |
key_id = str(uuid.uuid4())
|
| 112 |
-
|
| 113 |
"id": key_id,
|
| 114 |
"name": "",
|
| 115 |
"key": key_info,
|
|
@@ -122,20 +129,33 @@ class KeyManager:
|
|
| 122 |
"created_at": time.time(),
|
| 123 |
"last_used": None,
|
| 124 |
"notes": None
|
| 125 |
-
}
|
|
|
|
|
|
|
| 126 |
|
| 127 |
# 初始化使用统计
|
| 128 |
-
|
| 129 |
"total_requests": 0,
|
| 130 |
"successful_requests": 0,
|
| 131 |
"failed_requests": 0,
|
| 132 |
"daily_usage": {},
|
| 133 |
"average_response_time": 0
|
| 134 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
else:
|
| 136 |
# 新版格式:包含keys和usage_stats的字典
|
| 137 |
-
|
| 138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
| 140 |
def _save_keys(self) -> None:
|
| 141 |
"""保存密钥到文件"""
|
|
|
|
| 30 |
api_keys_str = os.getenv("API_KEYS", "")
|
| 31 |
if api_keys_str:
|
| 32 |
try:
|
| 33 |
+
logger.info(f"尝试从环境变量加载密钥,长度: {len(api_keys_str)}")
|
| 34 |
env_data = json.loads(api_keys_str)
|
| 35 |
+
logger.info(f"环境变量密钥数据类型: {type(env_data)}, 包含 {len(env_data) if isinstance(env_data, list) else '未知数量'} 个项目")
|
| 36 |
self._process_keys_data(env_data)
|
| 37 |
if len(self.keys) > 0:
|
| 38 |
logger.info(f"已从环境变量加载 {len(self.keys)} 个密钥")
|
|
|
|
| 42 |
except json.JSONDecodeError as e:
|
| 43 |
logger.error(f"解析环境变量API keys失败: {str(e)}")
|
| 44 |
|
| 45 |
+
# 如果环境变量未设置、解析失败或未加载到密钥,从文件加载
|
| 46 |
if not keys_loaded:
|
| 47 |
try:
|
| 48 |
if os.path.exists(self.storage_file):
|
| 49 |
logger.info(f"尝试从文件加载密钥: {self.storage_file}")
|
| 50 |
with open(self.storage_file, 'r', encoding='utf-8') as f:
|
| 51 |
data = json.load(f)
|
| 52 |
+
logger.info(f"文件密钥数据类型: {type(data)}, 数据: {json.dumps(data)[:100]}...")
|
| 53 |
keys_before = len(self.keys)
|
| 54 |
self._process_keys_data(data)
|
| 55 |
keys_loaded = len(self.keys) > keys_before
|
|
|
|
| 61 |
|
| 62 |
if len(self.keys) == 0:
|
| 63 |
logger.warning("未能从环境变量或文件加载任何密钥")
|
| 64 |
+
else:
|
| 65 |
+
logger.info(f"成功加载了 {len(self.keys)} 个密钥: {', '.join([k.get('name', k.get('id', '未命名')) for k in self.keys])}")
|
| 66 |
|
| 67 |
|
| 68 |
def _process_keys_data(self, data):
|
|
|
|
| 71 |
if isinstance(data, list):
|
| 72 |
# 旧版格式:直接是密钥列表
|
| 73 |
raw_keys = data
|
| 74 |
+
processed_keys = [] # 先存储到临时列表,不直接修改self.keys
|
| 75 |
+
temp_usage_stats = {} # 临时存储使用统计
|
| 76 |
|
| 77 |
# 为每个密钥创建完整的记录
|
| 78 |
for key_info in raw_keys:
|
| 79 |
+
logger.info(f"处理密钥: {type(key_info)}")
|
| 80 |
if isinstance(key_info, dict):
|
| 81 |
key_value = key_info.get("key")
|
| 82 |
if not key_value:
|
|
|
|
| 102 |
"notes": key_info.get("notes")
|
| 103 |
}
|
| 104 |
|
| 105 |
+
processed_keys.append(key_record)
|
| 106 |
+
logger.info(f"添加密钥: {key_record['name'] or key_id} (权重: {key_record['weight']})")
|
| 107 |
|
| 108 |
# 初始化使用统计
|
| 109 |
+
temp_usage_stats[key_id] = {
|
| 110 |
"total_requests": 0,
|
| 111 |
"successful_requests": 0,
|
| 112 |
"failed_requests": 0,
|
|
|
|
| 116 |
elif isinstance(key_info, str):
|
| 117 |
# 如果是字符串,直接作为密钥值
|
| 118 |
key_id = str(uuid.uuid4())
|
| 119 |
+
key_record = {
|
| 120 |
"id": key_id,
|
| 121 |
"name": "",
|
| 122 |
"key": key_info,
|
|
|
|
| 129 |
"created_at": time.time(),
|
| 130 |
"last_used": None,
|
| 131 |
"notes": None
|
| 132 |
+
}
|
| 133 |
+
processed_keys.append(key_record)
|
| 134 |
+
logger.info(f"添加字符串密钥: {key_id}")
|
| 135 |
|
| 136 |
# 初始化使用统计
|
| 137 |
+
temp_usage_stats[key_id] = {
|
| 138 |
"total_requests": 0,
|
| 139 |
"successful_requests": 0,
|
| 140 |
"failed_requests": 0,
|
| 141 |
"daily_usage": {},
|
| 142 |
"average_response_time": 0
|
| 143 |
}
|
| 144 |
+
|
| 145 |
+
# 更新keys和usage_stats
|
| 146 |
+
if processed_keys:
|
| 147 |
+
self.keys = processed_keys
|
| 148 |
+
self.usage_stats = temp_usage_stats
|
| 149 |
+
logger.info(f"处理完成,共 {len(self.keys)} 个密钥")
|
| 150 |
else:
|
| 151 |
# 新版格式:包含keys和usage_stats的字典
|
| 152 |
+
if 'keys' in data:
|
| 153 |
+
self.keys = data.get('keys', [])
|
| 154 |
+
self.usage_stats = data.get('usage_stats', {})
|
| 155 |
+
logger.info(f"从新格式加载了 {len(self.keys)} 个密钥")
|
| 156 |
+
else:
|
| 157 |
+
logger.warning(f"未知的数据格式: {type(data)}")
|
| 158 |
+
logger.warning(f"数据内容: {str(data)[:100]}...")
|
| 159 |
|
| 160 |
def _save_keys(self) -> None:
|
| 161 |
"""保存密钥到文件"""
|