yangtb24 commited on
Commit
6001b99
·
verified ·
1 Parent(s): 91ee28f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -25
app.py CHANGED
@@ -24,10 +24,7 @@ free_keys_global = []
24
  unverified_keys_global = []
25
  valid_keys_global = []
26
 
27
- # 使用 ThreadPoolExecutor 管理并发
28
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=20)
29
-
30
- # 为每个模型维护一个独立的 key 索引
31
  model_key_indices = {}
32
 
33
  def get_credit_summary(api_key):
@@ -220,23 +217,18 @@ def select_key(request_type, model_name):
220
  if not available_keys:
221
  return None
222
 
223
- # 获取当前模型的索引,如果没有则初始化为 0
224
  current_index = model_key_indices.get(model_name, 0)
225
 
226
- # 轮询并重试
227
  for _ in range(len(available_keys)):
228
  key = available_keys[current_index % len(available_keys)]
229
  current_index += 1
230
 
231
- # 检查 KEY 是否有效
232
  if key_is_valid(key, request_type):
233
- # 更新模型索引并返回 KEY
234
  model_key_indices[model_name] = current_index
235
  return key
236
  else:
237
  logging.warning(f"KEY {key} 无效或达到限制,尝试下一个 KEY")
238
 
239
- # 所有 KEY 都尝试过,重置索引并返回 None
240
  model_key_indices[model_name] = 0
241
  return None
242
 
@@ -245,7 +237,7 @@ def key_is_valid(key, request_type):
245
  检查 KEY 是否有效,根据不同的请求类型进行不同的检查。
246
  """
247
  if request_type == "invalid":
248
- return False # 无效 KEY 始终返回 False
249
 
250
  credit_summary = get_credit_summary(key)
251
  if credit_summary is None:
@@ -254,11 +246,11 @@ def key_is_valid(key, request_type):
254
  total_balance = credit_summary.get("total_balance", 0)
255
 
256
  if request_type == "free":
257
- return True # 免费 KEY,只要能获取到信息,就认为是有效的
258
  elif request_type == "paid" or request_type == "unverified":
259
- return total_balance > 0 # 付费 KEY 或未实名 KEY,需要余额大于 0 才是有效的
260
  else:
261
- return False # 未知类型,返回 False
262
 
263
  def check_authorization(request):
264
  """
@@ -290,10 +282,6 @@ def index():
290
 
291
  @app.route('/check_tokens', methods=['POST'])
292
  def check_tokens():
293
- """
294
- 处理前端发送的 Token 检测请求。
295
- 使用线程池并发处理每个 token。
296
- """
297
  tokens = request.json.get('tokens', [])
298
  test_model = os.environ.get("TEST_MODEL", "Pro/google/gemma-2-9b-it")
299
 
@@ -322,9 +310,6 @@ def check_tokens():
322
 
323
  @app.route('/handsome/v1/chat/completions', methods=['POST'])
324
  def handsome_chat_completions():
325
- """
326
- 处理 /handsome/v1/chat/completions 路由的请求,添加鉴权,并实现 KEY 的轮询和重试机制。
327
- """
328
  if not check_authorization(request):
329
  return jsonify({"error": "Unauthorized"}), 401
330
 
@@ -345,6 +330,7 @@ def handsome_chat_completions():
345
  }
346
 
347
  try:
 
348
  response = requests.post(
349
  TEST_MODEL_ENDPOINT,
350
  headers=headers,
@@ -357,10 +343,74 @@ def handsome_chat_completions():
357
  return jsonify(response.json()), 429
358
 
359
  if data.get("stream", False):
360
- return Response(stream_with_context(response.iter_content(chunk_size=1024)), content_type=response.headers['Content-Type'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  else:
362
  response.raise_for_status()
363
- return jsonify(response.json())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  except requests.exceptions.RequestException as e:
365
  return jsonify({"error": str(e)}), 500
366
 
@@ -375,10 +425,6 @@ def list_models():
375
  })
376
 
377
  def get_billing_info():
378
- """
379
- 获取所有KEY的额度信息。
380
- 使用线程池并发处理每个 key。
381
- """
382
  keys = valid_keys_global + unverified_keys_global
383
  total_balance = 0
384
 
@@ -451,6 +497,7 @@ def billing_subscription():
451
  })
452
 
453
  if __name__ == '__main__':
 
454
  logging.info(f"环境变量:{os.environ}")
455
 
456
  invalid_keys_global = []
 
24
  unverified_keys_global = []
25
  valid_keys_global = []
26
 
 
27
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=20)
 
 
28
  model_key_indices = {}
29
 
30
  def get_credit_summary(api_key):
 
217
  if not available_keys:
218
  return None
219
 
 
220
  current_index = model_key_indices.get(model_name, 0)
221
 
 
222
  for _ in range(len(available_keys)):
223
  key = available_keys[current_index % len(available_keys)]
224
  current_index += 1
225
 
 
226
  if key_is_valid(key, request_type):
 
227
  model_key_indices[model_name] = current_index
228
  return key
229
  else:
230
  logging.warning(f"KEY {key} 无效或达到限制,尝试下一个 KEY")
231
 
 
232
  model_key_indices[model_name] = 0
233
  return None
234
 
 
237
  检查 KEY 是否有效,根据不同的请求类型进行不同的检查。
238
  """
239
  if request_type == "invalid":
240
+ return False
241
 
242
  credit_summary = get_credit_summary(key)
243
  if credit_summary is None:
 
246
  total_balance = credit_summary.get("total_balance", 0)
247
 
248
  if request_type == "free":
249
+ return True
250
  elif request_type == "paid" or request_type == "unverified":
251
+ return total_balance > 0
252
  else:
253
+ return False
254
 
255
  def check_authorization(request):
256
  """
 
282
 
283
  @app.route('/check_tokens', methods=['POST'])
284
  def check_tokens():
 
 
 
 
285
  tokens = request.json.get('tokens', [])
286
  test_model = os.environ.get("TEST_MODEL", "Pro/google/gemma-2-9b-it")
287
 
 
310
 
311
  @app.route('/handsome/v1/chat/completions', methods=['POST'])
312
  def handsome_chat_completions():
 
 
 
313
  if not check_authorization(request):
314
  return jsonify({"error": "Unauthorized"}), 401
315
 
 
330
  }
331
 
332
  try:
333
+ start_time = time.time()
334
  response = requests.post(
335
  TEST_MODEL_ENDPOINT,
336
  headers=headers,
 
343
  return jsonify(response.json()), 429
344
 
345
  if data.get("stream", False):
346
+ def generate():
347
+ first_chunk_time = None
348
+ full_response_content = ""
349
+ for chunk in response.iter_content(chunk_size=1024):
350
+ if chunk:
351
+ if first_chunk_time is None:
352
+ first_chunk_time = time.time()
353
+ full_response_content += chunk.decode("utf-8")
354
+ yield chunk
355
+
356
+ end_time = time.time()
357
+ first_token_time = first_chunk_time - start_time if first_chunk_time else 0
358
+ total_time = end_time - start_time
359
+
360
+ # 从完整响应中提取信息
361
+ try:
362
+ response_json = json.loads(full_response_content.split("data: ")[-1].strip())
363
+ prompt_tokens = response_json["usage"]["prompt_tokens"]
364
+ completion_tokens = response_json["usage"]["completion_tokens"]
365
+ response_content = response_json["choices"][0]["message"]["content"]
366
+ except (KeyError, ValueError, IndexError):
367
+ prompt_tokens = 0
368
+ completion_tokens = 0
369
+ response_content = ""
370
+
371
+ # 提取用户输入的内容
372
+ user_content = ""
373
+ messages = data.get("messages", [])
374
+ for message in messages:
375
+ if message["role"] == "user":
376
+ user_content += message["content"] + " "
377
+ user_content = user_content.strip()
378
+
379
+ # 记录日志
380
+ logging.info(
381
+ f"使用的key: {api_key}, 提示token: {prompt_tokens}, 输出token: {completion_tokens}, ���字用时: {first_token_time:.4f}秒, 总共用时: {total_time:.4f}秒, 使用的模型: {model_name}, 用户的内容: {user_content}, 输出的内容: {response_content}"
382
+ )
383
+ return Response(stream_with_context(generate()), content_type=response.headers['Content-Type'])
384
  else:
385
  response.raise_for_status()
386
+ end_time = time.time()
387
+ response_json = response.json()
388
+ total_time = end_time - start_time
389
+
390
+ # 从响应中提取信息
391
+ try:
392
+ prompt_tokens = response_json["usage"]["prompt_tokens"]
393
+ completion_tokens = response_json["usage"]["completion_tokens"]
394
+ response_content = response_json["choices"][0]["message"]["content"]
395
+ except (KeyError, ValueError, IndexError):
396
+ prompt_tokens = 0
397
+ completion_tokens = 0
398
+ response_content = ""
399
+
400
+ # 提取用户输入的内容
401
+ user_content = ""
402
+ messages = data.get("messages", [])
403
+ for message in messages:
404
+ if message["role"] == "user":
405
+ user_content += message["content"] + " "
406
+ user_content = user_content.strip()
407
+
408
+ # 记录日志
409
+ logging.info(
410
+ f"使用的key: {api_key}, 提示token: {prompt_tokens}, 输出token: {completion_tokens}, 首字用时: 0, 总共用时: {total_time:.4f}秒, 使用的模型: {model_name}, 用户的内容: {user_content}, 输出的内容: {response_content}"
411
+ )
412
+ return jsonify(response_json)
413
+
414
  except requests.exceptions.RequestException as e:
415
  return jsonify({"error": str(e)}), 500
416
 
 
425
  })
426
 
427
  def get_billing_info():
 
 
 
 
428
  keys = valid_keys_global + unverified_keys_global
429
  total_balance = 0
430
 
 
497
  })
498
 
499
  if __name__ == '__main__':
500
+ import json
501
  logging.info(f"环境变量:{os.environ}")
502
 
503
  invalid_keys_global = []