yangtb24 commited on
Commit
2d342e6
·
verified ·
1 Parent(s): cbc7abf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -203
app.py CHANGED
@@ -56,17 +56,21 @@ session = requests_session_with_retries()
56
  app = Flask(__name__)
57
  app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)
58
 
59
- text_models = []
60
- free_text_models = []
61
- embedding_models = []
62
- free_embedding_models = []
63
- image_models = []
64
- free_image_models = []
65
-
66
- invalid_keys_global = []
67
- free_keys_global = []
68
- unverified_keys_global = []
69
- valid_keys_global = []
 
 
 
 
70
 
71
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=10000)
72
  model_key_indices = {}
@@ -112,30 +116,34 @@ FREE_IMAGE_LIST = [
112
  "stabilityai/stable-diffusion-2-1"
113
  ]
114
 
115
- def test_model_availability(api_key, model_name):
116
  headers = {
117
  "Authorization": f"Bearer {api_key}",
118
  "Content-Type": "application/json"
119
  }
 
 
 
 
120
  try:
 
 
 
 
 
 
 
 
121
  response = session.post(
122
- TEST_MODEL_ENDPOINT,
123
  headers=headers,
124
- json={
125
- "model": model_name,
126
- "messages": [{"role": "user", "content": "hi"}],
127
- "max_tokens": 5,
128
- "stream": False
129
- },
130
- timeout=5
131
  )
132
- if response.status_code == 429 or response.status_code == 200:
133
- return True
134
- else:
135
- return False
136
  except requests.exceptions.RequestException as e:
137
  logging.error(
138
- f"测试模型 {model_name} 可用性失败,"
139
  f"API Key:{api_key},错误信息:{e}"
140
  )
141
  return False
@@ -176,188 +184,109 @@ def create_base64_markdown_image(image_url):
176
  return None
177
 
178
  def refresh_models():
179
- global text_models, free_text_models
180
- global embedding_models, free_embedding_models
181
- global image_models, free_image_models
182
-
183
- text_models = get_all_models(FREE_MODEL_TEST_KEY, "chat")
184
- embedding_models = get_all_models(FREE_MODEL_TEST_KEY, "embedding")
185
- image_models = get_all_models(FREE_MODEL_TEST_KEY, "text-to-image")
186
- free_text_models = []
187
- free_embedding_models = []
188
- free_image_models = []
 
189
 
190
- ban_models_str = os.environ.get("BAN_MODELS")
191
  ban_models = []
 
192
  if ban_models_str:
193
  try:
194
  ban_models = json.loads(ban_models_str)
195
  if not isinstance(ban_models, list):
196
- logging.warning(
197
- "环境变量 BAN_MODELS 格式不正确,应为 JSON 数组。"
198
- )
199
  ban_models = []
200
  except json.JSONDecodeError:
201
- logging.warning(
202
- "环境变量 BAN_MODELS JSON 解析失败,请检查格式。"
203
- )
204
- ban_models = []
205
 
206
- text_models = [model for model in text_models if model not in ban_models]
207
- embedding_models = [model for model in embedding_models if model not in ban_models]
208
- image_models = [model for model in image_models if model not in ban_models]
209
-
210
- with concurrent.futures.ThreadPoolExecutor(
211
- max_workers=10000
212
- ) as executor:
213
- future_to_model = {
214
- executor.submit(
215
- test_model_availability,
216
- FREE_MODEL_TEST_KEY,
217
- model
218
- ): model for model in text_models
219
- }
220
- for future in concurrent.futures.as_completed(future_to_model):
221
- model = future_to_model[future]
222
- try:
223
- is_free = future.result()
224
- if is_free:
225
- free_text_models.append(model)
226
- except Exception as exc:
227
- logging.error(f"模型 {model} 测试生成异常: {exc}")
228
-
229
- with concurrent.futures.ThreadPoolExecutor(
230
- max_workers=10000
231
- ) as executor:
232
- future_to_model = {
233
- executor.submit(
234
- test_embedding_model_availability,
235
- FREE_MODEL_TEST_KEY, model
236
- ): model for model in embedding_models
237
- }
238
- for future in concurrent.futures.as_completed(future_to_model):
239
- model = future_to_model[future]
240
- try:
241
- is_free = future.result()
242
- if is_free:
243
- free_embedding_models.append(model)
244
- except Exception as exc:
245
- logging.error(f"模型 {model} 测试生成异常: {exc}")
246
-
247
- with concurrent.futures.ThreadPoolExecutor(
248
- max_workers=10000
249
- ) as executor:
250
- future_to_model = {
251
- executor.submit(
252
- test_image_model_availability,
253
- FREE_MODEL_TEST_KEY, model
254
- ): model for model in image_models
255
- }
256
- for future in concurrent.futures.as_completed(future_to_model):
257
- model = future_to_model[future]
258
- try:
259
- is_free = future.result()
260
- if is_free:
261
- free_image_models.append(model)
262
- except Exception as exc:
263
- logging.error(f"模型 {model} 测试生成异常: {exc}")
264
-
265
- logging.info(f"所有文本模型列表:{text_models}")
266
- logging.info(f"免费文本模型列表:{free_text_models}")
267
- logging.info(f"所有向量模型列表:{embedding_models}")
268
- logging.info(f"免费向量模型列表:{free_embedding_models}")
269
- logging.info(f"所有生图模型列表:{image_models}")
270
- logging.info(f"免费生图模型列表:{free_image_models}")
271
-
272
- def test_embedding_model_availability(api_key, model_name):
273
- headers = {
274
- "Authorization": f"Bearer {api_key}",
275
- "Content-Type": "application/json"
276
- }
277
- try:
278
- response = session.post(
279
- EMBEDDINGS_ENDPOINT,
280
- headers=headers,
281
- json={
282
- "model": model_name,
283
- "input": ["hi"],
284
- },
285
- timeout=10
286
- )
287
- if response.status_code == 429 or response.status_code == 200:
288
- return True
289
- else:
290
- return False
291
- except requests.exceptions.RequestException as e:
292
- logging.error(
293
- f"测试向量模型 {model_name} 可用性失败,"
294
- f"API Key:{api_key},错误信息:{e}"
295
- )
296
- return False
297
-
298
- def test_image_model_availability(api_key, model_name):
299
- return model_name in FREE_IMAGE_LIST
300
-
301
- def load_keys():
302
- keys_str = os.environ.get("KEYS")
303
- test_model = os.environ.get(
304
- "TEST_MODEL",
305
- "Pro/google/gemma-2-9b-it"
306
- )
307
-
308
- if keys_str:
309
- keys = [key.strip() for key in keys_str.split(',')]
310
- unique_keys = list(set(keys))
311
- keys_str = ','.join(unique_keys)
312
- os.environ["KEYS"] = keys_str
313
-
314
- logging.info(f"加载的 keys:{unique_keys}")
315
-
316
- with concurrent.futures.ThreadPoolExecutor(
317
- max_workers=10000
318
- ) as executor:
319
- future_to_key = {
320
  executor.submit(
321
- process_key, key, test_model
322
- ): key for key in unique_keys
 
 
 
323
  }
324
-
325
- invalid_keys = []
326
- free_keys = []
327
- unverified_keys = []
328
- valid_keys = []
329
-
330
- for future in concurrent.futures.as_completed(
331
- future_to_key
332
- ):
333
- key = future_to_key[future]
334
  try:
335
- key_type = future.result()
336
- if key_type == "invalid":
337
- invalid_keys.append(key)
338
- elif key_type == "free":
339
- free_keys.append(key)
340
- elif key_type == "unverified":
341
- unverified_keys.append(key)
342
- elif key_type == "valid":
343
- valid_keys.append(key)
344
  except Exception as exc:
345
- logging.error(f"处理 KEY {key} 生成异常: {exc}")
346
 
347
- logging.info(f"无效 KEY:{invalid_keys}")
348
- logging.info(f"免费 KEY:{free_keys}")
349
- logging.info(f"未实名 KEY:{unverified_keys}")
350
- logging.info(f"有效 KEY:{valid_keys}")
351
 
352
- global invalid_keys_global, free_keys_global
353
- global unverified_keys_global, valid_keys_global
354
- invalid_keys_global = invalid_keys
355
- free_keys_global = free_keys
356
- unverified_keys_global = unverified_keys
357
- valid_keys_global = valid_keys
358
 
359
- else:
 
 
 
 
 
 
 
360
  logging.warning("环境变量 KEYS 未设置。")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
 
362
  def process_key(key, test_model):
363
  credit_summary = get_credit_summary(key)
@@ -525,7 +454,14 @@ def list_models():
525
 
526
  detailed_models = []
527
 
528
- for model in chain(text_models, embedding_models, image_models):
 
 
 
 
 
 
 
529
  detailed_models.append({
530
  "id": model,
531
  "object": "model",
@@ -596,14 +532,14 @@ def handsome_embeddings():
596
  data = request.get_json()
597
  if not data or 'model' not in data:
598
  return jsonify({"error": "Invalid request data"}), 400
599
- if data['model'] not in embedding_models:
600
  return jsonify({"error": "Invalid model"}), 400
601
 
602
  model_name = data['model']
603
  request_type = determine_request_type(
604
  model_name,
605
- embedding_models,
606
- free_embedding_models
607
  )
608
  api_key = select_key(request_type, model_name)
609
 
@@ -677,15 +613,15 @@ def handsome_images_generations():
677
  data = request.get_json()
678
  if not data or 'model' not in data:
679
  return jsonify({"error": "Invalid request data"}), 400
680
- if data['model'] not in image_models:
681
  return jsonify({"error": "Invalid model"}), 400
682
 
683
  model_name = data.get('model')
684
 
685
  request_type = determine_request_type(
686
  model_name,
687
- image_models,
688
- free_image_models
689
  )
690
 
691
  api_key = select_key(request_type, model_name)
@@ -848,15 +784,15 @@ def handsome_chat_completions():
848
  data = request.get_json()
849
  if not data or 'model' not in data:
850
  return jsonify({"error": "Invalid request data"}), 400
851
- if data['model'] not in text_models and data['model'] not in image_models:
852
  return jsonify({"error": "Invalid model"}), 400
853
 
854
  model_name = data['model']
855
 
856
  request_type = determine_request_type(
857
  model_name,
858
- text_models + image_models,
859
- free_text_models + free_image_models
860
  )
861
 
862
  api_key = select_key(request_type, model_name)
@@ -877,7 +813,7 @@ def handsome_chat_completions():
877
  "Content-Type": "application/json"
878
  }
879
 
880
- if model_name in image_models:
881
  user_content = ""
882
  messages = data.get("messages", [])
883
  for message in messages:
@@ -1175,7 +1111,7 @@ def handsome_chat_completions():
1175
  headers=headers,
1176
  json=data,
1177
  stream=data.get("stream", False),
1178
- timeout=60
1179
  )
1180
 
1181
  if response.status_code == 429:
@@ -1388,4 +1324,4 @@ if __name__ == '__main__':
1388
  debug=False,
1389
  host='0.0.0.0',
1390
  port=int(os.environ.get('PORT', 7860))
1391
- )
 
56
  app = Flask(__name__)
57
  app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)
58
 
59
+ models = {
60
+ "text": [],
61
+ "free_text": [],
62
+ "embedding": [],
63
+ "free_embedding": [],
64
+ "image": [],
65
+ "free_image": []
66
+ }
67
+
68
+ key_status = {
69
+ "invalid": [],
70
+ "free": [],
71
+ "unverified": [],
72
+ "valid": []
73
+ }
74
 
75
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=10000)
76
  model_key_indices = {}
 
116
  "stabilityai/stable-diffusion-2-1"
117
  ]
118
 
119
+ def test_model_availability(api_key, model_name, model_type="chat"):
120
  headers = {
121
  "Authorization": f"Bearer {api_key}",
122
  "Content-Type": "application/json"
123
  }
124
+
125
+ if model_type == "image":
126
+ return model_name in FREE_IMAGE_LIST
127
+
128
  try:
129
+ endpoint = EMBEDDINGS_ENDPOINT if model_type == "embedding" else TEST_MODEL_ENDPOINT
130
+ payload = (
131
+ {"model": model_name, "input": ["hi"]}
132
+ if model_type == "embedding"
133
+ else {"model": model_name, "messages": [{"role": "user", "content": "hi"}], "max_tokens": 5, "stream": False}
134
+ )
135
+ timeout = 10 if model_type == "embedding" else 5
136
+
137
  response = session.post(
138
+ endpoint,
139
  headers=headers,
140
+ json=payload,
141
+ timeout=timeout
 
 
 
 
 
142
  )
143
+ return response.status_code in [200, 429]
 
 
 
144
  except requests.exceptions.RequestException as e:
145
  logging.error(
146
+ f"测试{model_type}模型 {model_name} 可用性失败,"
147
  f"API Key:{api_key},错误信息:{e}"
148
  )
149
  return False
 
184
  return None
185
 
186
  def refresh_models():
187
+ global models
188
+
189
+ # 获取各类型模型列表
190
+ models["text"] = get_all_models(FREE_MODEL_TEST_KEY, "chat")
191
+ models["embedding"] = get_all_models(FREE_MODEL_TEST_KEY, "embedding")
192
+ models["image"] = get_all_models(FREE_MODEL_TEST_KEY, "text-to-image")
193
+
194
+ # 重置免费模型列表
195
+ models["free_text"] = []
196
+ models["free_embedding"] = []
197
+ models["free_image"] = []
198
 
199
+ # 处理禁用模型
200
  ban_models = []
201
+ ban_models_str = os.environ.get("BAN_MODELS")
202
  if ban_models_str:
203
  try:
204
  ban_models = json.loads(ban_models_str)
205
  if not isinstance(ban_models, list):
206
+ logging.warning("环境变量 BAN_MODELS 格式不正确,应为 JSON 数组。")
 
 
207
  ban_models = []
208
  except json.JSONDecodeError:
209
+ logging.warning("环境变量 BAN_MODELS JSON 解析失败,请检查格式。")
 
 
 
210
 
211
+ # 过滤禁用模型
212
+ models["text"] = [model for model in models["text"] if model not in ban_models]
213
+ models["embedding"] = [model for model in models["embedding"] if model not in ban_models]
214
+ models["image"] = [model for model in models["image"] if model not in ban_models]
215
+
216
+ # 使用统一的测试函数测试各类型模型
217
+ model_types = [
218
+ ("text", "chat"),
219
+ ("embedding", "embedding"),
220
+ ("image", "image")
221
+ ]
222
+
223
+ for model_type, test_type in model_types:
224
+ with concurrent.futures.ThreadPoolExecutor(max_workers=10000) as executor:
225
+ future_to_model = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  executor.submit(
227
+ test_model_availability,
228
+ FREE_MODEL_TEST_KEY,
229
+ model,
230
+ test_type
231
+ ): model for model in models[model_type]
232
  }
233
+
234
+ for future in concurrent.futures.as_completed(future_to_model):
235
+ model = future_to_model[future]
 
 
 
 
 
 
 
236
  try:
237
+ is_free = future.result()
238
+ if is_free:
239
+ models[f"free_{model_type}"].append(model)
 
 
 
 
 
 
240
  except Exception as exc:
241
+ logging.error(f"{model_type}模型 {model} 测试生成异常: {exc}")
242
 
243
+ # 记录日志
244
+ for model_type in ["text", "embedding", "image"]:
245
+ logging.info(f"所有{model_type}模型列表:{models[model_type]}")
246
+ logging.info(f"免费{model_type}模型列表:{models[f'free_{model_type}']}")
247
 
 
 
 
 
 
 
248
 
249
+ def load_keys():
250
+ global key_status
251
+ # 重置key状态
252
+ for status in key_status:
253
+ key_status[status] = []
254
+
255
+ keys_str = os.environ.get("KEYS")
256
+ if not keys_str:
257
  logging.warning("环境变量 KEYS 未设置。")
258
+ return
259
+
260
+ test_model = os.environ.get("TEST_MODEL", "Pro/google/gemma-2-9b-it")
261
+ unique_keys = list(set(key.strip() for key in keys_str.split(',')))
262
+ os.environ["KEYS"] = ','.join(unique_keys)
263
+
264
+ logging.info(f"加载的 keys:{unique_keys}")
265
+
266
+ def process_key_with_logging(key):
267
+ try:
268
+ key_type = process_key(key, test_model)
269
+ if key_type in key_status:
270
+ key_status[key_type].append(key)
271
+ return key_type
272
+ except Exception as exc:
273
+ logging.error(f"处理 KEY {key} 生成异常: {exc}")
274
+ return "invalid"
275
+
276
+ with concurrent.futures.ThreadPoolExecutor(max_workers=10000) as executor:
277
+ futures = [executor.submit(process_key_with_logging, key) for key in unique_keys]
278
+ concurrent.futures.wait(futures)
279
+
280
+ # 记录每种状态的keys
281
+ for status, keys in key_status.items():
282
+ logging.info(f"{status.capitalize()} KEYS: {keys}")
283
+
284
+ # 更新全局变量
285
+ global invalid_keys_global, free_keys_global, unverified_keys_global, valid_keys_global
286
+ invalid_keys_global = key_status["invalid"]
287
+ free_keys_global = key_status["free"]
288
+ unverified_keys_global = key_status["unverified"]
289
+ valid_keys_global = key_status["valid"]
290
 
291
  def process_key(key, test_model):
292
  credit_summary = get_credit_summary(key)
 
454
 
455
  detailed_models = []
456
 
457
+ # 合并所有类型的模型
458
+ all_models = chain(
459
+ models["text"],
460
+ models["embedding"],
461
+ models["image"]
462
+ )
463
+
464
+ for model in all_models:
465
  detailed_models.append({
466
  "id": model,
467
  "object": "model",
 
532
  data = request.get_json()
533
  if not data or 'model' not in data:
534
  return jsonify({"error": "Invalid request data"}), 400
535
+ if data['model'] not in models["embedding"]:
536
  return jsonify({"error": "Invalid model"}), 400
537
 
538
  model_name = data['model']
539
  request_type = determine_request_type(
540
  model_name,
541
+ models["embedding"],
542
+ models["free_embedding"]
543
  )
544
  api_key = select_key(request_type, model_name)
545
 
 
613
  data = request.get_json()
614
  if not data or 'model' not in data:
615
  return jsonify({"error": "Invalid request data"}), 400
616
+ if data['model'] not in models["image"]:
617
  return jsonify({"error": "Invalid model"}), 400
618
 
619
  model_name = data.get('model')
620
 
621
  request_type = determine_request_type(
622
  model_name,
623
+ models["image"],
624
+ models["free_image"]
625
  )
626
 
627
  api_key = select_key(request_type, model_name)
 
784
  data = request.get_json()
785
  if not data or 'model' not in data:
786
  return jsonify({"error": "Invalid request data"}), 400
787
+ if data['model'] not in models["text"] and data['model'] not in models["image"]:
788
  return jsonify({"error": "Invalid model"}), 400
789
 
790
  model_name = data['model']
791
 
792
  request_type = determine_request_type(
793
  model_name,
794
+ models["text"] + models["image"],
795
+ models["free_text"] + models["free_image"]
796
  )
797
 
798
  api_key = select_key(request_type, model_name)
 
813
  "Content-Type": "application/json"
814
  }
815
 
816
+ if model_name in models["image"]:
817
  user_content = ""
818
  messages = data.get("messages", [])
819
  for message in messages:
 
1111
  headers=headers,
1112
  json=data,
1113
  stream=data.get("stream", False),
1114
+ timeout=600
1115
  )
1116
 
1117
  if response.status_code == 429:
 
1324
  debug=False,
1325
  host='0.0.0.0',
1326
  port=int(os.environ.get('PORT', 7860))
1327
+ )