| from flask import Flask, Response, request |
| import requests |
| import uuid |
| from datetime import datetime |
| import json |
| from flask_cors import CORS |
| import re |
| import random |
| import string |
|
|
| proxy = None |
| ua = 'Mozilla/5.0 (Windows NT 5.0) AppleWebKit/534.2 (KHTML, like Gecko) Chrome/59.0.865.0 Safari/534.2' |
| |
|
|
| if proxy: |
| proxies = {'http':proxy,'https':proxy} |
| else: |
| proxies = None |
|
|
| models = ['gpt_4', 'gpt_4_turbo', 'gpt_4o', 'claude_2', 'claude_3_opus', 'claude_3_sonnet', 'claude_3_haiku', 'gemini_pro', 'gemini_1_5_pro', 'databricks_dbrx_instruct', 'command_r', 'command_r_plus', 'zephyr', 'claude_3_opus_2k'] |
|
|
| headers = { |
| 'User-Agent': ua, |
| 'Accept': 'text/event-stream', |
| 'Referer': 'https://you.com/', |
| } |
|
|
|
|
|
|
| app = Flask(__name__) |
| CORS(app) |
|
|
| def update_files(content, cookies): |
| response = requests.get('https://you.com/api/get_nonce', cookies=cookies, headers=headers, proxies=proxies) |
| boundary = '----MyCustomBoundary' + ''.join(random.choices(string.ascii_letters + string.digits, k=16)) |
| user_filename = f'{"".join(random.choices(string.ascii_letters + string.digits, k=5))}.txt' |
| multipart_data = ( |
| '--' + boundary + '\r\n' + |
| f'Content-Disposition: form-data; name="file"; filename={user_filename}\r\n' + |
| 'Content-Type: text/plain\r\n\r\n' + |
| content |
| +'\r\n' |
| '--' + boundary + '--' |
| ) |
| headers123 = { |
| 'User-Agent': ua, |
| 'Accept': 'text/event-stream', |
| 'Referer': 'https://you.com/', |
| 'accept': 'multipart/form-data', |
| 'accept-language': 'cmn', |
| 'content-type': 'multipart/form-data; boundary=' + boundary, |
| 'x-upload-nonce': response.text, |
| 'Content-Length': str(len(content.encode('utf-8'))), |
| } |
| response = requests.post('https://you.com/api/upload', headers=headers123, data=multipart_data.encode('utf-8'), cookies=cookies, proxies=proxies) |
| filename = response.json()['filename'] |
| return filename, user_filename, str(len(content.encode('utf-8'))) |
|
|
| def get_ck_parms(session, session_jwt, chat, chatid, model): |
| cookies = { |
| 'youpro_subscription': 'true', |
| 'stytch_session': session, |
| 'stytch_session_jwt': session_jwt, |
| 'ydc_stytch_session': session, |
| 'ydc_stytch_session_jwt': session_jwt, |
| } |
| params = {'q': chat, |
| 'page': '1', |
| 'count': '10', |
| 'safeSearch': |
| 'Moderate', 'mkt': |
| 'zh-HK', 'responseFilter': |
| 'WebPages,TimeZone,Computation,RelatedSearches', |
| 'domain': 'youchat', |
| 'use_personalization_extraction': 'true', |
| 'queryTraceId': chatid, |
| 'chatId': chatid, |
| 'conversationTurnId': '75f82567-3f79-4f4d-bdbc-48847c23cab3', |
| 'pastChatLength': '0', |
| 'isSmallMediumDevice': 'true', |
| 'selectedChatMode': 'custom', |
| 'selectedAiModel': model, |
| 'traceId': f'{chatid}|{uuid.uuid4()}|{datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ")}', |
| 'chat': '[]' |
| } |
| return cookies,params |
|
|
| def parse_1(data): |
| messages = data['messages'] |
| model = data['model'] |
| try: |
| _stream = data['stream'] |
| except: |
| _stream = False |
|
|
| if '使用四到五个字直接返回这句话的简要主题,不要解释、不要标点、不要语气词、不要多余文本,不要加粗,如果没有主题,请直接返回“闲聊”' in str(messages): |
| model = 'gpt_4_turbo' |
| if model == 'gem_pro': |
| model = 'gemini_pro' |
| elif model == 'gem_1_5_pro': |
| model = 'gemini_1_5_pro' |
| elif model not in models: |
| model = 'gpt_4_turbo' |
| if model == 'command_r' or model == 'zephyr' or model == 'claude_2': |
| add_t = "This is the api format of our previous conversation, please understand and reply to the user's last question" |
| messages = add_t + str(messages) |
| elif model == 'databricks_dbrx_instruct' or model == 'gemini_pro'or model == 'gemini_1_5_pro' or model == 'claude_3_opus_2k': |
| for item in reversed(messages): |
| if item['role'] == 'user': |
| messages = item['content'] |
| break |
| return str(messages),model,_stream |
|
|
| def chat_liu(chat, model, session, session_jwt): |
| chatid = uuid.uuid4() |
| cookies,params = get_ck_parms(session, session_jwt, chat, chatid, model) |
| response = requests.get( |
| 'https://you.com/api/streamingSearch', |
| cookies=cookies, |
| headers=headers, |
| params=params, |
| stream=True, |
| proxies=proxies |
| ) |
| if response.status_code == 200: |
| for line in response.iter_lines(): |
| if line: |
| data = line.decode('utf-8') |
| if 'event' in data: |
| continue |
| else: |
| data = data[6:] |
| if 'youChatToken' in data: |
| id = str(uuid.uuid4()) |
| content = json.loads(data)['youChatToken'] |
| if 'Please log in to access GPT-4 mode.' in content and 'Answering your question without GPT-4 mode:' in content: |
| content = 'cookie失效或会员到期,将默认使用智障模型!\n\n' |
| yield "data: {}\n\n".format(json.dumps({ |
| "id": "chatcmpl-"+id, |
| "created": 0, |
| "model": model, |
| "choices": [{ |
| "index": 0, |
| "delta": { |
| "content": content, |
| } |
| }] |
| })) |
| yield bytes(f"data: {['DONE']}", 'utf-8') |
| yield bytes() |
| else: |
| if response.status_code == 403 and 'Just a moment...' in response.text: |
| print('盾') |
| return response.status_code |
| |
| def claude_3_opus_2k(chat, model, session, session_jwt): |
| model = 'claude_3_opus' |
| cookies = { |
| 'youpro_subscription': 'true', |
| 'stytch_session': session, |
| 'stytch_session_jwt': session_jwt, |
| 'ydc_stytch_session': session, |
| 'ydc_stytch_session_jwt': session_jwt, |
| } |
|
|
| with open('wb.txt', 'r', encoding='utf-8') as file: |
| content = file.read() |
| filename, user_filename, size = update_files(content.replace('{tihuan1145141919810}', chat), cookies) |
| chatid = str(uuid.uuid4()) |
| params = {'q': 'Please review the attached prompt', 'page': '1', 'count': '10', 'safeSearch': 'Moderate', 'mkt': 'zh-HK', 'responseFilter': 'WebPages,TimeZone,Computation,RelatedSearches', 'domain': 'youchat', 'use_personalization_extraction': 'true', |
| 'queryTraceId': chatid, |
| 'chatId': chatid, |
| 'conversationTurnId': str(uuid.uuid4()), |
| 'pastChatLength': '0', 'isSmallMediumDevice': 'true', 'selectedChatMode': 'custom', |
| 'userFiles': '[{"user_filename":"' + user_filename + '","filename":"' + filename + '","size":"' + size + '"}]', |
| 'selectedAIModel': 'claude_3_opus', |
| 'traceId': f'{chatid}|{uuid.uuid4()}|{datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ")}', |
| 'chat': '[]'} |
| response = requests.get( |
| 'https://you.com/api/streamingSearch', |
| cookies=cookies, |
| headers=headers, |
| params=params, |
| stream=True, |
| proxies=proxies, |
| timeout=500 |
| ) |
| if response.status_code == 200: |
| for line in response.iter_lines(): |
| if line: |
| data = line.decode('utf-8') |
| if 'event' in data: |
| continue |
| else: |
| data = data[6:] |
| if 'youChatToken' in data: |
| id = str(uuid.uuid4()) |
| content = json.loads(data)['youChatToken'] |
| if 'Please log in to access GPT-4 mode.' in content and 'Answering your question without GPT-4 mode:' in content: |
| content = 'cookie失效或会员到期,将默认使用智障模型!\n\n' |
| yield "data: {}\n\n".format(json.dumps({ |
| "id": "chatcmpl-"+id, |
| "created": 0, |
| "model": model, |
| "choices": [{ |
| "index": 0, |
| "delta": { |
| "content": content, |
| } |
| }] |
| })) |
| yield bytes(f"data: {['DONE']}", 'utf-8') |
| yield bytes() |
| else: |
| if response.status_code == 403 and 'Just a moment...' in response.text: |
| print('盾') |
| return response.status_code |
|
|
| def chat_feiliu(chat, model, session, session_jwt): |
| chatid = uuid.uuid4() |
| cookies,params = get_ck_parms(session, session_jwt, chat, chatid, model) |
| response = requests.get( |
| 'https://you.com/api/streamingSearch', |
| cookies=cookies, |
| headers=headers, |
| params=params, |
| stream=True, |
| proxies=proxies |
| ) |
| chat_text = '' |
| if response.status_code == 200: |
| for line in response.iter_lines(): |
| if line: |
| data = line.decode('utf-8') |
| if 'event' in data: |
| continue |
| else: |
| data = data[6:] |
| if 'youChatToken' in data: |
| id = str(uuid.uuid4()) |
| content = json.loads(data)['youChatToken'] |
| if 'Please log in to access GPT-4 mode.' in content and 'Answering your question without GPT-4 mode:' in content: |
| content = 'cookie失效或会员到期,将默认使用智障模型!\n\n' |
| chat_text = chat_text + content |
| else: |
| return {"error": f'返回错误|{str(response.status_code)}'}, response.status_code |
| return {"id":f"chatcmpl-{str(uuid.uuid4())}", |
| "OAI-Device-Id":str(uuid.uuid4()), |
| "conversation_id":str(uuid.uuid4()), |
| "created":123, |
| "model":"gpt-3.5-turbo", |
| "choices":[{"index":0,"message":{"role":"assistant","content":chat_text},"finish_reason":"stop"}], |
| "usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}} |
|
|
|
|
| @app.route('/') |
| def stream(): |
| return 'ok' |
| |
| @app.route('/v1/chat/completions', methods=['POST', 'OPTIONS']) |
| def chatv1_1(): |
| if request.method == 'OPTIONS': |
| return '', 204 |
| try: |
| try: |
| session_jwt = re.search(r'stytch_session_jwt=([^;]+)', request.headers.get('Authorization')).group(1) |
| session = re.search(r'ydc_stytch_session=([^;]+)', request.headers.get('Authorization')).group(1) |
| except: |
| return {"error": "请确保传入的Authorization正确"}, 401 |
| try: |
| messages,model,_stream = parse_1(request.get_json()) |
| except Exception as e: |
| print(e) |
| return {"error": "Invalid JSON body1"}, 404 |
| try: |
| if model == 'claude_3_opus_2k': |
| if _stream == False: |
| return {"error": "Only supports stream mode"}, 404 |
| return Response(claude_3_opus_2k(str(messages), model, session, session_jwt), mimetype='text/event-stream') |
| except: |
| return {"error": "Upload error or membership expiration"}, 404 |
|
|
| if _stream == True: |
| return Response(chat_liu(str(messages), model, session, session_jwt), mimetype='text/event-stream') |
| else: |
| return chat_feiliu(messages, model, session, session_jwt) |
| except Exception as e: |
| print('error') |
| print(e) |
| return {"error": "Invalid JSON body"}, 404 |
|
|
| if __name__ == '__main__': |
| app.run(host='0.0.0.0', debug=True, port=8000) |