Spaces:
Paused
Paused
| from flask import Flask, request, Response, jsonify, stream_with_context | |
| import requests | |
| import json | |
| import uuid | |
| import time | |
| app = Flask(__name__) | |
| def chat_completions(): | |
| auth_header = request.headers.get('Authorization', '') | |
| if auth_header.startswith('Bearer '): | |
| token = auth_header[7:] | |
| else: | |
| return jsonify({"error": "Authorization header must be a Bearer token"}), 401 | |
| try: | |
| openai_request = request.json | |
| messages = openai_request.get('messages', []) | |
| user_message = "" | |
| for msg in reversed(messages): | |
| if msg.get('role') == 'user': | |
| user_message = msg.get('content', '') | |
| break | |
| if not user_message: | |
| return jsonify({"error": "No user message found"}), 400 | |
| yun_api_url = 'https://ai.yun.139.com/api/outer/assistant/chat/add' | |
| yun_headers = { | |
| 'User-Agent': 'Mozilla/5.0 (Linux; Android 14; 23049RAD8C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/118.0.0.0 Mobile Safari/537.36 MCloudApp/11.4.4', | |
| 'Accept': 'text/event-stream', | |
| 'Content-Type': 'application/json', | |
| 'sec-ch-ua': '"Chromium";v="118", "Android WebView";v="118", "Not=A?Brand";v="99"', | |
| 'x-yun-app-channel': '101', | |
| 'sec-ch-ua-mobile': '?1', | |
| 'authorization': f'Basic {token}', | |
| 'x-yun-api-version': 'v4', | |
| 'sec-ch-ua-platform': '"Android"', | |
| 'origin': 'https://yun.139.com', | |
| 'x-requested-with': 'com.chinamobile.mcloud', | |
| 'sec-fetch-site': 'same-site', | |
| 'sec-fetch-mode': 'cors', | |
| 'sec-fetch-dest': 'empty', | |
| 'referer': 'https://yun.139.com/', | |
| 'accept-language': 'zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7' | |
| } | |
| yun_data = { | |
| "userId": "", | |
| "sessionId": "", | |
| "content": { | |
| "dialogue": user_message, | |
| "prompt": "", | |
| "commands": "", | |
| "resourceType": "0", | |
| "resourceId": "", | |
| "dialogueType": "0", | |
| "sourceChannel": "101", | |
| "extInfo": "{\"h5Version\":\"1.7.4\"}" | |
| }, | |
| "applicationType": "chat", | |
| "applicationId": "" | |
| } | |
| stream_mode = openai_request.get('stream', False) | |
| if stream_mode: | |
| def generate(): | |
| response_id = f"chatcmpl-{str(uuid.uuid4())}" | |
| start_time = time.time() | |
| response = requests.post(yun_api_url, headers=yun_headers, json=yun_data, stream=True) | |
| collected_text = "" | |
| for line in response.iter_lines(): | |
| if line: | |
| line_text = line.decode('utf-8') | |
| if line_text.startswith('data:'): | |
| data_json = json.loads(line_text[5:].strip()) | |
| if 'content' in data_json: | |
| delta_text = data_json['content'] | |
| collected_text += delta_text | |
| chunk = { | |
| "id": response_id, | |
| "object": "chat.completion.chunk", | |
| "created": int(time.time()), | |
| "model": "DeepSeek-R1", | |
| "choices": [ | |
| { | |
| "index": 0, | |
| "delta": { | |
| "content": delta_text | |
| }, | |
| "finish_reason": None | |
| } | |
| ] | |
| } | |
| yield f"data: {json.dumps(chunk)}\n\n" | |
| final_chunk = { | |
| "id": response_id, | |
| "object": "chat.completion.chunk", | |
| "created": int(time.time()), | |
| "model": "DeepSeek-R1", | |
| "choices": [ | |
| { | |
| "index": 0, | |
| "delta": {}, | |
| "finish_reason": "stop" | |
| } | |
| ] | |
| } | |
| yield f"data: {json.dumps(final_chunk)}\n\n" | |
| yield "data: [DONE]\n\n" | |
| return Response(stream_with_context(generate()), content_type='text/event-stream') | |
| else: | |
| response = requests.post(yun_api_url, headers=yun_headers, json=yun_data) | |
| response_data = response.json() | |
| assistant_message = "" | |
| if 'data' in response_data and 'content' in response_data['data']: | |
| assistant_message = response_data['data']['content'] | |
| openai_response = { | |
| "id": f"chatcmpl-{str(uuid.uuid4())}", | |
| "object": "chat.completion", | |
| "created": int(time.time()), | |
| "model": "DeepSeek-R1", | |
| "choices": [ | |
| { | |
| "index": 0, | |
| "message": { | |
| "role": "assistant", | |
| "content": assistant_message | |
| }, | |
| "finish_reason": "stop" | |
| } | |
| ], | |
| "usage": { | |
| "prompt_tokens": len(user_message), | |
| "completion_tokens": len(assistant_message), | |
| "total_tokens": len(user_message) + len(assistant_message) | |
| } | |
| } | |
| return jsonify(openai_response) | |
| except Exception as e: | |
| return jsonify({"error": str(e)}), 500 | |
| def list_models(): | |
| models = { | |
| "object": "list", | |
| "data": [ | |
| { | |
| "id": "DeepSeek-R1", | |
| "object": "model", | |
| "created": int(time.time()), | |
| "owned_by": "139.com" | |
| } | |
| ] | |
| } | |
| return jsonify(models) | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=8080, debug=True) |