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,
|