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