import requests
import json
from flask import Flask, request, Response
import time
import configparser
import uuid

app = Flask(__name__)

# 读取配置文件
config = configparser.ConfigParser()
config.read('config.ini')

# 全局变量用于保存 UUID
saved_uuid = None

@app.route('/chat', methods=['POST'])
def chat():
    global saved_uuid

    # 记录开始时间
    start_time = time.time()

    # 解析请求
    req_data = request.json
    sid = req_data.get('sid')
    dh_code = req_data.get('dh-code')
    dh_question = req_data.get('dh-question')
    dh_conversation_id = req_data.get('dh-conversation-id')
    dh_context = req_data.get('dh-context', "{}")
    api_key = request.args.get('api_key')  # 从请求路径中获取 api_key
    print(api_key)
    # print(dh_context)
    print(dh_conversation_id)

    # 检查 dh_context 是否为 None，如果是则生成一个新的 UUID
    if dh_context is None:
        saved_uuid = str(uuid.uuid4())
    dh_conversation_id = saved_uuid

    # 根据 api_key 设置 Authorization 头
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    # 构建请求数据
    data = {
        "chatId": dh_conversation_id,
        "stream": True,
        "detail": False,
        "messages": [
            {
                "content": dh_question,
                "role": "user"
            }
        ]
    }

    # 发送流式POST请求到xyai.cloud
    url = config['API']['url']
    api_response = requests.post(url, headers=headers, data=json.dumps(data), stream=True)

    # 处理流式响应
    def generate():
        buffer = ""
        separators = "，。！？；"  # 分隔符列表
        if api_response.status_code == 200:
            for line in api_response.iter_lines():
                if line:
                    decoded_line = line.decode('utf-8')
                    if decoded_line.startswith("data: "):
                        try:
                            json_data = json.loads(decoded_line[6:])
                            if json_data.get("choices"):
                                delta = json_data["choices"][0].get("delta")
                                if delta and delta.get("content"):
                                    content = delta["content"]
                                    buffer += content
                                    # 检查是否遇到分隔符
                                    for sep in separators:
                                        if sep in buffer:
                                            parts = buffer.split(sep)
                                            for part in parts[:-1]:
                                                yield json.dumps({"answer": part + sep, "isEnd": False}) + "\n"
                                            buffer = parts[-1]
                                            break
                                elif json_data["choices"][0].get("finish_reason") == "stop":
                                    if buffer:
                                        yield json.dumps({"answer": buffer, "isEnd": False}) + "\n"
                                    yield json.dumps({"answer": "", "isEnd": True}) + "\n"
                                    return  # 退出生成器函数
                        except json.JSONDecodeError as e:
                            if decoded_line[6:] != "[DONE]":
                                print(f"JSONDecodeError: {e}, line: {decoded_line[6:]}")
                            else:
                                if buffer:
                                    yield json.dumps({"answer": buffer, "isEnd": False}) + "\n"
                                yield json.dumps({"answer": "", "isEnd": True}) + "\n"
                                return  # 退出生成器函数
        else:
            yield json.dumps({"answer": f"Error: {api_response.status_code}", "isEnd": True}) + "\n"

    # 返回流式响应
    response = Response(generate(), content_type='application/json')

    # 记录结束时间并计算耗时
    end_time = time.time()
    elapsed_time = end_time - start_time
    print(f"Request processed in {elapsed_time:.2f} seconds")

    return response

if __name__ == '__main__':
    app.run(debug=True, port=5001, use_reloader=False)
--------
这个代码有什么漏洞？