Update app.py
Browse files
app.py
CHANGED
@@ -18,7 +18,7 @@ os.environ['TZ'] = 'Asia/Shanghai'
|
|
18 |
time.tzset()
|
19 |
|
20 |
logging.basicConfig(level=logging.INFO,
|
21 |
-
format='%(asctime)s - %(levelname)s - %(message)s')
|
22 |
|
23 |
API_ENDPOINT = "https://api.siliconflow.cn/v1/user/info"
|
24 |
TEST_MODEL_ENDPOINT = "https://api.siliconflow.cn/v1/chat/completions"
|
@@ -46,6 +46,15 @@ request_timestamps = []
|
|
46 |
token_counts = []
|
47 |
data_lock = threading.Lock()
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
def get_credit_summary(api_key):
|
50 |
"""
|
51 |
使用 API 密钥获取额度信息。
|
@@ -469,7 +478,6 @@ def index():
|
|
469 |
one_minute_ago = current_time - 60
|
470 |
|
471 |
with data_lock:
|
472 |
-
# Clean up old data
|
473 |
while request_timestamps and request_timestamps[0] < one_minute_ago:
|
474 |
request_timestamps.pop(0)
|
475 |
token_counts.pop(0)
|
@@ -544,7 +552,8 @@ def check_tokens():
|
|
544 |
)
|
545 |
except Exception as exc:
|
546 |
logging.error(
|
547 |
-
f"处理 Token {token} 生成异常: {exc}"
|
|
|
548 |
)
|
549 |
|
550 |
return jsonify(results)
|
@@ -774,7 +783,8 @@ def handsome_embeddings():
|
|
774 |
except (KeyError, ValueError, IndexError) as e:
|
775 |
logging.error(
|
776 |
f"解析响应 JSON 失败: {e}, "
|
777 |
-
f"完整内容: {response_json}"
|
|
|
778 |
)
|
779 |
prompt_tokens = 0
|
780 |
embedding_data = []
|
@@ -783,7 +793,8 @@ def handsome_embeddings():
|
|
783 |
f"使用的key: {api_key}, "
|
784 |
f"提示token: {prompt_tokens}, "
|
785 |
f"总共用时: {total_time:.4f}秒, "
|
786 |
-
f"使用的模型: {model_name}"
|
|
|
787 |
)
|
788 |
|
789 |
with data_lock:
|
@@ -937,12 +948,12 @@ def handsome_images_generations():
|
|
937 |
img_str = base64.b64encode(buffered.getvalue()).decode()
|
938 |
openai_images.append({"b64_json": img_str})
|
939 |
except Exception as e:
|
940 |
-
logging.error(f"图片转base64失败: {e}")
|
941 |
openai_images.append({"url": image_url})
|
942 |
else:
|
943 |
openai_images.append({"url": image_url})
|
944 |
else:
|
945 |
-
logging.error(f"无效的图片数据: {item}")
|
946 |
openai_images.append({"url": item})
|
947 |
|
948 |
|
@@ -953,7 +964,8 @@ def handsome_images_generations():
|
|
953 |
except (KeyError, ValueError, IndexError) as e:
|
954 |
logging.error(
|
955 |
f"解析响应 JSON 失败: {e}, "
|
956 |
-
f"完整内容: {response_json}"
|
|
|
957 |
)
|
958 |
response_data = {
|
959 |
"created": int(time.time()),
|
@@ -963,7 +975,8 @@ def handsome_images_generations():
|
|
963 |
logging.info(
|
964 |
f"使用的key: {api_key}, "
|
965 |
f"总共用时: {total_time:.4f}秒, "
|
966 |
-
f"使用的模型: {model_name}"
|
|
|
967 |
)
|
968 |
|
969 |
with data_lock:
|
@@ -973,7 +986,7 @@ def handsome_images_generations():
|
|
973 |
return jsonify(response_data)
|
974 |
|
975 |
except requests.exceptions.RequestException as e:
|
976 |
-
logging.error(f"请求转发异常: {e}")
|
977 |
return jsonify({"error": str(e)}), 500
|
978 |
else:
|
979 |
return jsonify({"error": "Unsupported model"}), 400
|
@@ -1131,10 +1144,10 @@ def handsome_chat_completions():
|
|
1131 |
image_url = ""
|
1132 |
if images and isinstance(images[0], dict) and "url" in images[0]:
|
1133 |
image_url = images[0]["url"]
|
1134 |
-
logging.info(f"Extracted image URL: {image_url}")
|
1135 |
elif images and isinstance(images[0], str):
|
1136 |
image_url = images[0]
|
1137 |
-
logging.info(f"Extracted image URL: {image_url}")
|
1138 |
|
1139 |
markdown_image_link = f""
|
1140 |
if image_url:
|
@@ -1194,7 +1207,7 @@ def handsome_chat_completions():
|
|
1194 |
request_timestamps.append(time.time())
|
1195 |
token_counts.append(0)
|
1196 |
except requests.exceptions.RequestException as e:
|
1197 |
-
logging.error(f"请求转发异常: {e}")
|
1198 |
error_chunk_data = {
|
1199 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
1200 |
"object": "chat.completion.chunk",
|
@@ -1228,7 +1241,8 @@ def handsome_chat_completions():
|
|
1228 |
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
1229 |
logging.info(
|
1230 |
f"使用的key: {api_key}, "
|
1231 |
-
f"使用的模型: {model_name}"
|
|
|
1232 |
)
|
1233 |
yield "data: [DONE]\n\n".encode('utf-8')
|
1234 |
return Response(stream_with_context(generate()), content_type='text/event-stream')
|
@@ -1245,10 +1259,10 @@ def handsome_chat_completions():
|
|
1245 |
image_url = ""
|
1246 |
if images and isinstance(images[0], dict) and "url" in images[0]:
|
1247 |
image_url = images[0]["url"]
|
1248 |
-
logging.info(f"Extracted image URL: {image_url}")
|
1249 |
elif images and isinstance(images[0], str):
|
1250 |
image_url = images[0]
|
1251 |
-
logging.info(f"Extracted image URL: {image_url}")
|
1252 |
|
1253 |
markdown_image_link = f""
|
1254 |
response_data = {
|
@@ -1270,7 +1284,8 @@ def handsome_chat_completions():
|
|
1270 |
except (KeyError, ValueError, IndexError) as e:
|
1271 |
logging.error(
|
1272 |
f"解析响应 JSON 失败: {e}, "
|
1273 |
-
f"完整内容: {response_json}"
|
|
|
1274 |
)
|
1275 |
response_data = {
|
1276 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
@@ -1292,7 +1307,8 @@ def handsome_chat_completions():
|
|
1292 |
logging.info(
|
1293 |
f"使用的key: {api_key}, "
|
1294 |
f"总共用时: {total_time:.4f}秒, "
|
1295 |
-
f"使用的模型: {model_name}"
|
|
|
1296 |
)
|
1297 |
with data_lock:
|
1298 |
request_timestamps.append(time.time())
|
@@ -1300,7 +1316,7 @@ def handsome_chat_completions():
|
|
1300 |
return jsonify(response_data)
|
1301 |
|
1302 |
except requests.exceptions.RequestException as e:
|
1303 |
-
logging.error(f"请求转发异常: {e}")
|
1304 |
return jsonify({"error": str(e)}), 500
|
1305 |
else:
|
1306 |
try:
|
@@ -1325,7 +1341,7 @@ def handsome_chat_completions():
|
|
1325 |
chunk = chunk.decode('utf-8')
|
1326 |
yield f"{chunk}\n\n".encode('utf-8')
|
1327 |
except requests.exceptions.RequestException as e:
|
1328 |
-
logging.error(f"请求转发异常: {e}")
|
1329 |
error_chunk_data = {
|
1330 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
1331 |
"object": "chat.completion.chunk",
|
@@ -1392,7 +1408,8 @@ def handsome_chat_completions():
|
|
1392 |
except (KeyError, ValueError, IndexError) as e:
|
1393 |
logging.error(
|
1394 |
f"解析响应 JSON 失败: {e}, "
|
1395 |
-
f"完整内容: {response_json}"
|
|
|
1396 |
)
|
1397 |
response_data = {
|
1398 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
@@ -1414,19 +1431,20 @@ def handsome_chat_completions():
|
|
1414 |
logging.info(
|
1415 |
f"使用的key: {api_key}, "
|
1416 |
f"总共用时: {total_time:.4f}秒, "
|
1417 |
-
f"使用的模型: {model_name}"
|
|
|
1418 |
)
|
1419 |
with data_lock:
|
1420 |
request_timestamps.append(time.time())
|
1421 |
token_counts.append(0)
|
1422 |
return jsonify(response_data)
|
1423 |
except requests.exceptions.RequestException as e:
|
1424 |
-
logging.error(f"请求转发异常: {e}")
|
1425 |
return jsonify({"error": str(e)}), 500
|
1426 |
|
1427 |
if __name__ == '__main__':
|
1428 |
import json
|
1429 |
-
logging.info(f"环境变量:{os.environ}")
|
1430 |
|
1431 |
invalid_keys_global = []
|
1432 |
free_keys_global = []
|
@@ -1434,14 +1452,14 @@ if __name__ == '__main__':
|
|
1434 |
valid_keys_global = []
|
1435 |
|
1436 |
load_keys()
|
1437 |
-
logging.info("程序启动时首次加载 keys 已执行")
|
1438 |
|
1439 |
scheduler.start()
|
1440 |
|
1441 |
-
logging.info("首次加载 keys 已手动触发执行")
|
1442 |
|
1443 |
refresh_models()
|
1444 |
-
logging.info("首次刷新模型列表已手动触发执行")
|
1445 |
|
1446 |
app.run(
|
1447 |
debug=False,
|
|
|
18 |
time.tzset()
|
19 |
|
20 |
logging.basicConfig(level=logging.INFO,
|
21 |
+
format='%(asctime)s - %(levelname)s - %(client_ip)s - %(message)s')
|
22 |
|
23 |
API_ENDPOINT = "https://api.siliconflow.cn/v1/user/info"
|
24 |
TEST_MODEL_ENDPOINT = "https://api.siliconflow.cn/v1/chat/completions"
|
|
|
46 |
token_counts = []
|
47 |
data_lock = threading.Lock()
|
48 |
|
49 |
+
def get_client_ip():
|
50 |
+
"""
|
51 |
+
获取客户端IP地址。
|
52 |
+
"""
|
53 |
+
if request.headers.getlist("X-Forwarded-For"):
|
54 |
+
return request.headers.getlist("X-Forwarded-For")[0]
|
55 |
+
else:
|
56 |
+
return request.remote_addr
|
57 |
+
|
58 |
def get_credit_summary(api_key):
|
59 |
"""
|
60 |
使用 API 密钥获取额度信息。
|
|
|
478 |
one_minute_ago = current_time - 60
|
479 |
|
480 |
with data_lock:
|
|
|
481 |
while request_timestamps and request_timestamps[0] < one_minute_ago:
|
482 |
request_timestamps.pop(0)
|
483 |
token_counts.pop(0)
|
|
|
552 |
)
|
553 |
except Exception as exc:
|
554 |
logging.error(
|
555 |
+
f"处理 Token {token} 生成异常: {exc}",
|
556 |
+
extra={'client_ip': get_client_ip()}
|
557 |
)
|
558 |
|
559 |
return jsonify(results)
|
|
|
783 |
except (KeyError, ValueError, IndexError) as e:
|
784 |
logging.error(
|
785 |
f"解析响应 JSON 失败: {e}, "
|
786 |
+
f"完整内容: {response_json}",
|
787 |
+
extra={'client_ip': get_client_ip()}
|
788 |
)
|
789 |
prompt_tokens = 0
|
790 |
embedding_data = []
|
|
|
793 |
f"使用的key: {api_key}, "
|
794 |
f"提示token: {prompt_tokens}, "
|
795 |
f"总共用时: {total_time:.4f}秒, "
|
796 |
+
f"使用的模型: {model_name}",
|
797 |
+
extra={'client_ip': get_client_ip()}
|
798 |
)
|
799 |
|
800 |
with data_lock:
|
|
|
948 |
img_str = base64.b64encode(buffered.getvalue()).decode()
|
949 |
openai_images.append({"b64_json": img_str})
|
950 |
except Exception as e:
|
951 |
+
logging.error(f"图片转base64失败: {e}", extra={'client_ip': get_client_ip()})
|
952 |
openai_images.append({"url": image_url})
|
953 |
else:
|
954 |
openai_images.append({"url": image_url})
|
955 |
else:
|
956 |
+
logging.error(f"无效的图片数据: {item}", extra={'client_ip': get_client_ip()})
|
957 |
openai_images.append({"url": item})
|
958 |
|
959 |
|
|
|
964 |
except (KeyError, ValueError, IndexError) as e:
|
965 |
logging.error(
|
966 |
f"解析响应 JSON 失败: {e}, "
|
967 |
+
f"完整内容: {response_json}",
|
968 |
+
extra={'client_ip': get_client_ip()}
|
969 |
)
|
970 |
response_data = {
|
971 |
"created": int(time.time()),
|
|
|
975 |
logging.info(
|
976 |
f"使用的key: {api_key}, "
|
977 |
f"总共用时: {total_time:.4f}秒, "
|
978 |
+
f"使用的模型: {model_name}",
|
979 |
+
extra={'client_ip': get_client_ip()}
|
980 |
)
|
981 |
|
982 |
with data_lock:
|
|
|
986 |
return jsonify(response_data)
|
987 |
|
988 |
except requests.exceptions.RequestException as e:
|
989 |
+
logging.error(f"请求转发异常: {e}", extra={'client_ip': get_client_ip()})
|
990 |
return jsonify({"error": str(e)}), 500
|
991 |
else:
|
992 |
return jsonify({"error": "Unsupported model"}), 400
|
|
|
1144 |
image_url = ""
|
1145 |
if images and isinstance(images[0], dict) and "url" in images[0]:
|
1146 |
image_url = images[0]["url"]
|
1147 |
+
logging.info(f"Extracted image URL: {image_url}", extra={'client_ip': get_client_ip()})
|
1148 |
elif images and isinstance(images[0], str):
|
1149 |
image_url = images[0]
|
1150 |
+
logging.info(f"Extracted image URL: {image_url}", extra={'client_ip': get_client_ip()})
|
1151 |
|
1152 |
markdown_image_link = f""
|
1153 |
if image_url:
|
|
|
1207 |
request_timestamps.append(time.time())
|
1208 |
token_counts.append(0)
|
1209 |
except requests.exceptions.RequestException as e:
|
1210 |
+
logging.error(f"请求转发异常: {e}", extra={'client_ip': get_client_ip()})
|
1211 |
error_chunk_data = {
|
1212 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
1213 |
"object": "chat.completion.chunk",
|
|
|
1241 |
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
1242 |
logging.info(
|
1243 |
f"使用的key: {api_key}, "
|
1244 |
+
f"使用的模型: {model_name}",
|
1245 |
+
extra={'client_ip': get_client_ip()}
|
1246 |
)
|
1247 |
yield "data: [DONE]\n\n".encode('utf-8')
|
1248 |
return Response(stream_with_context(generate()), content_type='text/event-stream')
|
|
|
1259 |
image_url = ""
|
1260 |
if images and isinstance(images[0], dict) and "url" in images[0]:
|
1261 |
image_url = images[0]["url"]
|
1262 |
+
logging.info(f"Extracted image URL: {image_url}", extra={'client_ip': get_client_ip()})
|
1263 |
elif images and isinstance(images[0], str):
|
1264 |
image_url = images[0]
|
1265 |
+
logging.info(f"Extracted image URL: {image_url}", extra={'client_ip': get_client_ip()})
|
1266 |
|
1267 |
markdown_image_link = f""
|
1268 |
response_data = {
|
|
|
1284 |
except (KeyError, ValueError, IndexError) as e:
|
1285 |
logging.error(
|
1286 |
f"解析响应 JSON 失败: {e}, "
|
1287 |
+
f"完整内容: {response_json}",
|
1288 |
+
extra={'client_ip': get_client_ip()}
|
1289 |
)
|
1290 |
response_data = {
|
1291 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
|
|
1307 |
logging.info(
|
1308 |
f"使用的key: {api_key}, "
|
1309 |
f"总共用时: {total_time:.4f}秒, "
|
1310 |
+
f"使用的模型: {model_name}",
|
1311 |
+
extra={'client_ip': get_client_ip()}
|
1312 |
)
|
1313 |
with data_lock:
|
1314 |
request_timestamps.append(time.time())
|
|
|
1316 |
return jsonify(response_data)
|
1317 |
|
1318 |
except requests.exceptions.RequestException as e:
|
1319 |
+
logging.error(f"请求转发异常: {e}", extra={'client_ip': get_client_ip()})
|
1320 |
return jsonify({"error": str(e)}), 500
|
1321 |
else:
|
1322 |
try:
|
|
|
1341 |
chunk = chunk.decode('utf-8')
|
1342 |
yield f"{chunk}\n\n".encode('utf-8')
|
1343 |
except requests.exceptions.RequestException as e:
|
1344 |
+
logging.error(f"请求转发异常: {e}", extra={'client_ip': get_client_ip()})
|
1345 |
error_chunk_data = {
|
1346 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
1347 |
"object": "chat.completion.chunk",
|
|
|
1408 |
except (KeyError, ValueError, IndexError) as e:
|
1409 |
logging.error(
|
1410 |
f"解析响应 JSON 失败: {e}, "
|
1411 |
+
f"完整内容: {response_json}",
|
1412 |
+
extra={'client_ip': get_client_ip()}
|
1413 |
)
|
1414 |
response_data = {
|
1415 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
|
|
1431 |
logging.info(
|
1432 |
f"使用的key: {api_key}, "
|
1433 |
f"总共用时: {total_time:.4f}秒, "
|
1434 |
+
f"使用的模型: {model_name}",
|
1435 |
+
extra={'client_ip': get_client_ip()}
|
1436 |
)
|
1437 |
with data_lock:
|
1438 |
request_timestamps.append(time.time())
|
1439 |
token_counts.append(0)
|
1440 |
return jsonify(response_data)
|
1441 |
except requests.exceptions.RequestException as e:
|
1442 |
+
logging.error(f"请求转发异常: {e}", extra={'client_ip': get_client_ip()})
|
1443 |
return jsonify({"error": str(e)}), 500
|
1444 |
|
1445 |
if __name__ == '__main__':
|
1446 |
import json
|
1447 |
+
logging.info(f"环境变量:{os.environ}", extra={'client_ip': get_client_ip()})
|
1448 |
|
1449 |
invalid_keys_global = []
|
1450 |
free_keys_global = []
|
|
|
1452 |
valid_keys_global = []
|
1453 |
|
1454 |
load_keys()
|
1455 |
+
logging.info("程序启动时首次加载 keys 已执行", extra={'client_ip': get_client_ip()})
|
1456 |
|
1457 |
scheduler.start()
|
1458 |
|
1459 |
+
logging.info("首次加载 keys 已手动触发执行", extra={'client_ip': get_client_ip()})
|
1460 |
|
1461 |
refresh_models()
|
1462 |
+
logging.info("首次刷新模型列表已手动触发执行", extra={'client_ip': get_client_ip()})
|
1463 |
|
1464 |
app.run(
|
1465 |
debug=False,
|