From 10534a670b2e682421237ed3f1ebd56d6b61d5f2 Mon Sep 17 00:00:00 2001 From: 27942 <1313123@342> Date: Thu, 22 Jan 2026 19:47:25 +0800 Subject: [PATCH] haha --- main.py | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..ac407a1 --- /dev/null +++ b/main.py @@ -0,0 +1,194 @@ +import requests +import json +import sys + +headers = { + 'accept': 'application/json, text/event-stream', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'authorization': 'Bearer sk-hOdY292wluz2aFrLCe5f1cdscnjdksnjkNKJNJNJKNKJ1769082037063', + 'cache-control': 'no-cache', + 'content-type': 'application/json', + 'dnt': '1', + 'newauth': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mjk4MSwic2Vzc2lvbiI6IjQ3YmFlYTBlNDY0ZDA0YWU3YjYwYjJiZDQ5YTQ2Y2RlIn0.PWjowAqaBepISCdp1XvwwbjRZi8jrrwNE8BntT6VQHs', + 'origin': 'https://proai520.com', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://proai520.com/', + 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Microsoft Edge";v="144"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'token': '85bb99fa1ae0b45caa50346f26479285', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0', + 'username': 'ojAPQ6mcTExxYLTrA7HjGnG7803I', +} + +json_data = { + 'messages': [ + { + 'role': 'system', + 'content': '\nYou are ChatGPT, a large language model trained by OpenAI.\nKnowledge cutoff: 2021-09\nCurrent model: gpt-5.2\nCurrent time: Thu Jan 22 2026 19:40:37 GMT+0800 (中国标准时间)\nLatex inline: \\(x^2\\) \nLatex block: $$e=mc^2$$\n\n', + }, + { + 'role': 'user', + 'content': '你好,你是谁', + }, + ], + 'stream': True, + 'model': 'gpt-5.2', + 'temperature': 0.5, + 'presence_penalty': 0, + 'frequency_penalty': 0, + 'top_p': 1, + 'max_tokens': 8000, +} + + +def parse_sse_stream(response): + """ + 解析 SSE (Server-Sent Events) 流式响应 + 返回 OpenAI 兼容格式的完整响应 + """ + full_content = "" + response_id = None + model = None + created = None + usage = None + + # 逐行解析 SSE 流 + for line in response.iter_lines(decode_unicode=True): + if not line: + continue + + # SSE 格式: data: {json} + if line.startswith('data: '): + data_str = line[6:] # 移除 'data: ' 前缀 + + # 检查是否是结束标记 + if data_str.strip() == '[DONE]': + break + + try: + chunk = json.loads(data_str) + + # 提取元数据 + if response_id is None and 'id' in chunk: + response_id = chunk['id'] + if model is None and 'model' in chunk: + model = chunk['model'] + if created is None and 'created' in chunk: + created = chunk['created'] + if usage is None and 'usage' in chunk: + usage = chunk['usage'] + + # 提取内容增量 + if 'choices' in chunk and len(chunk['choices']) > 0: + choice = chunk['choices'][0] + if 'delta' in choice and 'content' in choice['delta']: + content_delta = choice['delta']['content'] + full_content += content_delta + + except json.JSONDecodeError as e: + # 忽略无法解析的行 + continue + + # 构建 OpenAI 兼容格式的完整响应 + openai_response = { + "id": response_id or "chatcmpl-unknown", + "object": "chat.completion", + "created": created or 0, + "model": model or json_data.get('model', 'unknown'), + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": full_content + }, + "finish_reason": "stop" + } + ], + "usage": usage or { + "prompt_tokens": 0, + "completion_tokens": 0, + "total_tokens": 0 + } + } + + return openai_response + + +def stream_sse_response(response): + """ + 流式输出 SSE 响应,转换为 OpenAI 兼容格式 + 每个 chunk 输出为 OpenAI 流式格式 + """ + for line in response.iter_lines(decode_unicode=True): + if not line: + continue + + if line.startswith('data: '): + data_str = line[6:] + + if data_str.strip() == '[DONE]': + # 输出结束标记 + print('data: [DONE]\n') + break + + try: + chunk = json.loads(data_str) + + # 转换为 OpenAI 流式格式 + openai_chunk = { + "id": chunk.get('id', 'chatcmpl-unknown'), + "object": "chat.completion.chunk", + "created": chunk.get('created', 0), + "model": chunk.get('model', json_data.get('model', 'unknown')), + "choices": [] + } + + if 'choices' in chunk and len(chunk['choices']) > 0: + original_choice = chunk['choices'][0] + openai_choice = { + "index": 0, + "delta": original_choice.get('delta', {}), + "finish_reason": original_choice.get('finish_reason') + } + openai_chunk["choices"] = [openai_choice] + + # 输出 OpenAI 格式的 chunk + print(f"data: {json.dumps(openai_chunk, ensure_ascii=False)}\n") + sys.stdout.flush() + + except json.JSONDecodeError: + continue + + +# 发送请求 +response = requests.post( + 'https://api.proai520.com/v1/chat/completions', + headers=headers, + json=json_data, + stream=True # 启用流式响应 +) + +# 方式1: 解析为完整的 OpenAI 格式响应(非流式) +print("=" * 60) +print("方式1: 完整响应格式(非流式)") +print("=" * 60) +complete_response = parse_sse_stream(response) +print(json.dumps(complete_response, ensure_ascii=False, indent=2)) + +# 如果需要流式输出,可以使用以下代码(需要重新发送请求) +# print("\n" + "=" * 60) +# print("方式2: 流式响应格式") +# print("=" * 60) +# response2 = requests.post( +# 'https://api.proai520.com/v1/chat/completions', +# headers=headers, +# json=json_data, +# stream=True +# ) +# stream_sse_response(response2)