Update app.py
Browse files
app.py
CHANGED
|
@@ -7,6 +7,9 @@ import random
|
|
| 7 |
import uuid
|
| 8 |
import concurrent.futures
|
| 9 |
import threading
|
|
|
|
|
|
|
|
|
|
| 10 |
from datetime import datetime, timedelta
|
| 11 |
from apscheduler.schedulers.background import BackgroundScheduler
|
| 12 |
from flask import Flask, request, jsonify, Response, stream_with_context
|
|
@@ -582,8 +585,6 @@ def handsome_chat_completions():
|
|
| 582 |
}
|
| 583 |
|
| 584 |
if model_name in image_models:
|
| 585 |
-
# Handle image generation
|
| 586 |
-
# Map OpenAI-style parameters to SiliconFlow's parameters
|
| 587 |
siliconflow_data = {
|
| 588 |
"model": model_name,
|
| 589 |
"prompt": data.get("messages", [{}])[0].get("content") if isinstance(data.get("messages"), list) else "",
|
|
@@ -630,8 +631,6 @@ def handsome_chat_completions():
|
|
| 630 |
|
| 631 |
if data.get("stream", False):
|
| 632 |
def generate():
|
| 633 |
-
first_chunk_time = None
|
| 634 |
-
full_response_content = ""
|
| 635 |
try:
|
| 636 |
response.raise_for_status()
|
| 637 |
end_time = time.time()
|
|
@@ -650,6 +649,12 @@ def handsome_chat_completions():
|
|
| 650 |
logging.info(f"Extracted image URL: {image_url}")
|
| 651 |
|
| 652 |
if image_url:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 653 |
chunk_data = {
|
| 654 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
| 655 |
"object": "chat.completion.chunk",
|
|
@@ -660,14 +665,66 @@ def handsome_chat_completions():
|
|
| 660 |
"index": 0,
|
| 661 |
"delta": {
|
| 662 |
"role": "assistant",
|
| 663 |
-
"content":
|
| 664 |
},
|
| 665 |
"finish_reason": None
|
| 666 |
}
|
| 667 |
]
|
| 668 |
}
|
| 669 |
yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
|
| 670 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 671 |
else:
|
| 672 |
chunk_data = {
|
| 673 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
|
@@ -686,26 +743,20 @@ def handsome_chat_completions():
|
|
| 686 |
]
|
| 687 |
}
|
| 688 |
yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
|
| 689 |
-
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
}
|
| 704 |
-
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
| 705 |
-
|
| 706 |
-
with data_lock:
|
| 707 |
-
request_timestamps.append(time.time())
|
| 708 |
-
token_counts.append(0) # Image generation doesn't use tokens
|
| 709 |
except requests.exceptions.RequestException as e:
|
| 710 |
logging.error(f"请求转发异常: {e}")
|
| 711 |
error_chunk_data = {
|
|
@@ -739,12 +790,9 @@ def handsome_chat_completions():
|
|
| 739 |
]
|
| 740 |
}
|
| 741 |
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
| 742 |
-
|
| 743 |
-
logging.info(
|
| 744 |
-
f"使用的key: {api_key}, "
|
| 745 |
-
f"使用的模型: {model_name}"
|
| 746 |
-
)
|
| 747 |
yield "data: [DONE]\n\n".encode('utf-8')
|
|
|
|
| 748 |
return Response(stream_with_context(generate()), content_type='text/event-stream')
|
| 749 |
else:
|
| 750 |
response.raise_for_status()
|
|
@@ -755,7 +803,6 @@ def handsome_chat_completions():
|
|
| 755 |
try:
|
| 756 |
images = response_json.get("images", [])
|
| 757 |
|
| 758 |
-
# Extract the first URL if available
|
| 759 |
image_url = ""
|
| 760 |
if images and isinstance(images[0], dict) and "url" in images[0]:
|
| 761 |
image_url = images[0]["url"]
|
|
@@ -812,7 +859,7 @@ def handsome_chat_completions():
|
|
| 812 |
|
| 813 |
with data_lock:
|
| 814 |
request_timestamps.append(time.time())
|
| 815 |
-
token_counts.append(0)
|
| 816 |
|
| 817 |
return jsonify(response_data)
|
| 818 |
except requests.exceptions.RequestException as e:
|
|
@@ -1270,10 +1317,6 @@ def handsome_embeddings():
|
|
| 1270 |
except requests.exceptions.RequestException as e:
|
| 1271 |
return jsonify({"error": str(e)}), 500
|
| 1272 |
|
| 1273 |
-
import base64
|
| 1274 |
-
import io
|
| 1275 |
-
from PIL import Image
|
| 1276 |
-
|
| 1277 |
@app.route('/handsome/v1/images/generations', methods=['POST'])
|
| 1278 |
def handsome_images_generations():
|
| 1279 |
if not check_authorization(request):
|
|
@@ -1312,7 +1355,6 @@ def handsome_images_generations():
|
|
| 1312 |
response_data = {}
|
| 1313 |
|
| 1314 |
if "stable-diffusion" in model_name:
|
| 1315 |
-
# Map OpenAI-style parameters to SiliconFlow's parameters
|
| 1316 |
siliconflow_data = {
|
| 1317 |
"model": model_name,
|
| 1318 |
"prompt": data.get("prompt"),
|
|
@@ -1325,7 +1367,6 @@ def handsome_images_generations():
|
|
| 1325 |
"prompt_enhancement": False,
|
| 1326 |
}
|
| 1327 |
|
| 1328 |
-
# Parameter validation and adjustments
|
| 1329 |
if siliconflow_data["batch_size"] < 1:
|
| 1330 |
siliconflow_data["batch_size"] = 1
|
| 1331 |
if siliconflow_data["batch_size"] > 4:
|
|
@@ -1410,7 +1451,7 @@ def handsome_images_generations():
|
|
| 1410 |
|
| 1411 |
with data_lock:
|
| 1412 |
request_timestamps.append(time.time())
|
| 1413 |
-
token_counts.append(0)
|
| 1414 |
|
| 1415 |
return jsonify(response_data)
|
| 1416 |
|
|
|
|
| 7 |
import uuid
|
| 8 |
import concurrent.futures
|
| 9 |
import threading
|
| 10 |
+
import base64
|
| 11 |
+
import io
|
| 12 |
+
from PIL import Image
|
| 13 |
from datetime import datetime, timedelta
|
| 14 |
from apscheduler.schedulers.background import BackgroundScheduler
|
| 15 |
from flask import Flask, request, jsonify, Response, stream_with_context
|
|
|
|
| 585 |
}
|
| 586 |
|
| 587 |
if model_name in image_models:
|
|
|
|
|
|
|
| 588 |
siliconflow_data = {
|
| 589 |
"model": model_name,
|
| 590 |
"prompt": data.get("messages", [{}])[0].get("content") if isinstance(data.get("messages"), list) else "",
|
|
|
|
| 631 |
|
| 632 |
if data.get("stream", False):
|
| 633 |
def generate():
|
|
|
|
|
|
|
| 634 |
try:
|
| 635 |
response.raise_for_status()
|
| 636 |
end_time = time.time()
|
|
|
|
| 649 |
logging.info(f"Extracted image URL: {image_url}")
|
| 650 |
|
| 651 |
if image_url:
|
| 652 |
+
image_response = requests.get(image_url, stream=True)
|
| 653 |
+
image_response.raise_for_status()
|
| 654 |
+
|
| 655 |
+
|
| 656 |
+
first_chunk_time = time.time()
|
| 657 |
+
|
| 658 |
chunk_data = {
|
| 659 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
| 660 |
"object": "chat.completion.chunk",
|
|
|
|
| 665 |
"index": 0,
|
| 666 |
"delta": {
|
| 667 |
"role": "assistant",
|
| 668 |
+
"content": ""
|
| 669 |
},
|
| 670 |
"finish_reason": None
|
| 671 |
}
|
| 672 |
]
|
| 673 |
}
|
| 674 |
yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
|
| 675 |
+
|
| 676 |
+
for chunk in image_response.iter_content(chunk_size=1024):
|
| 677 |
+
if chunk:
|
| 678 |
+
chunk_data = {
|
| 679 |
+
"id": f"chatcmpl-{uuid.uuid4()}",
|
| 680 |
+
"object": "chat.completion.chunk",
|
| 681 |
+
"created": int(time.time()),
|
| 682 |
+
"model": model_name,
|
| 683 |
+
"choices": [
|
| 684 |
+
{
|
| 685 |
+
"index": 0,
|
| 686 |
+
"delta": {
|
| 687 |
+
"role": "assistant",
|
| 688 |
+
"content": chunk.decode('latin-1',errors='ignore')
|
| 689 |
+
},
|
| 690 |
+
"finish_reason": None
|
| 691 |
+
}
|
| 692 |
+
]
|
| 693 |
+
}
|
| 694 |
+
yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
|
| 695 |
+
|
| 696 |
+
end_chunk_data = {
|
| 697 |
+
"id": f"chatcmpl-{uuid.uuid4()}",
|
| 698 |
+
"object": "chat.completion.chunk",
|
| 699 |
+
"created": int(time.time()),
|
| 700 |
+
"model": model_name,
|
| 701 |
+
"choices": [
|
| 702 |
+
{
|
| 703 |
+
"index": 0,
|
| 704 |
+
"delta": {},
|
| 705 |
+
"finish_reason": "stop"
|
| 706 |
+
}
|
| 707 |
+
]
|
| 708 |
+
}
|
| 709 |
+
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
| 710 |
+
|
| 711 |
+
first_token_time = (
|
| 712 |
+
first_chunk_time - start_time
|
| 713 |
+
if first_chunk_time else 0
|
| 714 |
+
)
|
| 715 |
+
total_time = end_time - start_time
|
| 716 |
+
|
| 717 |
+
logging.info(
|
| 718 |
+
f"使用的key: {api_key}, "
|
| 719 |
+
f"首字用时: {first_token_time:.4f}秒, "
|
| 720 |
+
f"总共用时: {total_time:.4f}秒, "
|
| 721 |
+
f"使用的模型: {model_name}"
|
| 722 |
+
)
|
| 723 |
+
|
| 724 |
+
with data_lock:
|
| 725 |
+
request_timestamps.append(time.time())
|
| 726 |
+
token_counts.append(0)
|
| 727 |
+
|
| 728 |
else:
|
| 729 |
chunk_data = {
|
| 730 |
"id": f"chatcmpl-{uuid.uuid4()}",
|
|
|
|
| 743 |
]
|
| 744 |
}
|
| 745 |
yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
|
| 746 |
+
end_chunk_data = {
|
| 747 |
+
"id": f"chatcmpl-{uuid.uuid4()}",
|
| 748 |
+
"object": "chat.completion.chunk",
|
| 749 |
+
"created": int(time.time()),
|
| 750 |
+
"model": model_name,
|
| 751 |
+
"choices": [
|
| 752 |
+
{
|
| 753 |
+
"index": 0,
|
| 754 |
+
"delta": {},
|
| 755 |
+
"finish_reason": "stop"
|
| 756 |
+
}
|
| 757 |
+
]
|
| 758 |
+
}
|
| 759 |
+
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 760 |
except requests.exceptions.RequestException as e:
|
| 761 |
logging.error(f"请求转发异常: {e}")
|
| 762 |
error_chunk_data = {
|
|
|
|
| 790 |
]
|
| 791 |
}
|
| 792 |
yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
|
| 793 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 794 |
yield "data: [DONE]\n\n".encode('utf-8')
|
| 795 |
+
|
| 796 |
return Response(stream_with_context(generate()), content_type='text/event-stream')
|
| 797 |
else:
|
| 798 |
response.raise_for_status()
|
|
|
|
| 803 |
try:
|
| 804 |
images = response_json.get("images", [])
|
| 805 |
|
|
|
|
| 806 |
image_url = ""
|
| 807 |
if images and isinstance(images[0], dict) and "url" in images[0]:
|
| 808 |
image_url = images[0]["url"]
|
|
|
|
| 859 |
|
| 860 |
with data_lock:
|
| 861 |
request_timestamps.append(time.time())
|
| 862 |
+
token_counts.append(0)
|
| 863 |
|
| 864 |
return jsonify(response_data)
|
| 865 |
except requests.exceptions.RequestException as e:
|
|
|
|
| 1317 |
except requests.exceptions.RequestException as e:
|
| 1318 |
return jsonify({"error": str(e)}), 500
|
| 1319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1320 |
@app.route('/handsome/v1/images/generations', methods=['POST'])
|
| 1321 |
def handsome_images_generations():
|
| 1322 |
if not check_authorization(request):
|
|
|
|
| 1355 |
response_data = {}
|
| 1356 |
|
| 1357 |
if "stable-diffusion" in model_name:
|
|
|
|
| 1358 |
siliconflow_data = {
|
| 1359 |
"model": model_name,
|
| 1360 |
"prompt": data.get("prompt"),
|
|
|
|
| 1367 |
"prompt_enhancement": False,
|
| 1368 |
}
|
| 1369 |
|
|
|
|
| 1370 |
if siliconflow_data["batch_size"] < 1:
|
| 1371 |
siliconflow_data["batch_size"] = 1
|
| 1372 |
if siliconflow_data["batch_size"] > 4:
|
|
|
|
| 1451 |
|
| 1452 |
with data_lock:
|
| 1453 |
request_timestamps.append(time.time())
|
| 1454 |
+
token_counts.append(0)
|
| 1455 |
|
| 1456 |
return jsonify(response_data)
|
| 1457 |
|