ykl45 commited on
Commit
3963725
1 Parent(s): 715f132

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +36 -73
main.py CHANGED
@@ -1,85 +1,48 @@
1
- from fastapi import FastAPI, Request, Response, HTTPException
2
- from starlette.responses import StreamingResponse
3
- from starlette.status import HTTP_401_UNAUTHORIZED
4
  import requests
5
- import json
6
- import os
7
 
8
- app = FastAPI()
9
 
10
- @app.middleware("http")
11
- async def api_key_auth(request: Request, call_next):
12
- apikey = os.getenv('apikey')
13
- if (request.method == 'POST') and (request.url.path in ['/yyds/v1/chat/completions']):
14
- if not apikey:
15
- response = await call_next(request)
16
- return response
17
- auth_header = request.headers.get('Authorization')
18
- if not auth_header or not auth_header.startswith('Bearer '):
19
- return Response(content="缺少授权信息", status_code=HTTP_401_UNAUTHORIZED)
20
- token = auth_header.split(" ")[1]
21
- if token != apikey:
22
- return Response(content="授权失败", status_code=HTTP_401_UNAUTHORIZED)
23
- response = await call_next(request)
24
- return response
25
 
26
- # FastAPI uses Pydantic to parse the request body into python object
27
- @app.post("/yyds/v1/chat/completions")
28
- @app.options("/yyds/v1/chat/completions") # This maps to the appropriate URL
29
- async def main(request: Request):
30
- if request.method != 'POST':
31
- return Response(None, status_code=204, headers={
32
- 'Access-Control-Allow-Origin': '*',
33
- "Access-Control-Allow-Headers": '*',
34
- 'Content-Type': 'text/event-stream',
35
- 'Cache-Control': 'no-cache',
36
- 'Connection': 'keep-alive'
37
- })
38
 
39
- headers = dict(request.headers)
40
- # Add or modify headers
41
- headers['Content-Type'] = 'application/json'
 
42
 
43
- url = 'https://multillm.ai-pro.org/api/openai-completion' # target API address
44
- headers ={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", "Content-Type": "application/json"}
45
- jsonData = await request.json()
46
- jsonData["stream"] = True
47
- response = requests.post(url, headers=headers, json=jsonData) # Send the request
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- if response.status_code != 200:
50
- return Response(content='Unable to reach the backend API', status_code=502)
 
 
51
 
52
- response_data = response.json()
53
- return StreamingResponse(
54
- event_stream(response_data),
55
- headers={
56
- 'Access-Control-Allow-Origin': '*',
57
- "Access-Control-Allow-Headers": '*',
58
- 'Content-Type': 'text/event-stream',
59
- 'Cache-Control': 'no-cache',
60
- 'Connection': 'keep-alive'
61
- }
62
- )
63
 
 
 
64
 
 
65
 
66
- def event_stream(data):
67
- # Simplified eventStream function that does not split the content into chunks
68
- output = json.dumps({
69
- "id": data['id'],
70
- "object": 'chat.completion.chunk',
71
- "created": data['created'],
72
- "model": data['model'],
73
- "system_fingerprint": data['system_fingerprint'],
74
- "choices": [{
75
- "index": 0,
76
- "delta": {"role": 'assistant', "content": data['choices'][0]['message']['content']},
77
- "logprobs": None,
78
- "finish_reason": data['choices'][0]['finish_reason']
79
- }]
80
- })
81
- yield f'data: {output}\n\n' # The StreamingResponse expects an iterable
82
 
83
- if __name__ == "__main__":
84
- import uvicorn
85
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
+ from flask import Flask, request, Response, stream_with_context
 
 
2
  import requests
 
 
3
 
4
+ app = Flask(__name__)
5
 
6
+ # 你想代理的网址
7
+ PROXY_TARGET = "https://chatpro.ai-pro.org"
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ @app.route('/', defaults={'path': ''})
11
+ @app.route('/<path:path>', methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
12
+ def proxy(path):
13
+ global PROXY_TARGET
14
 
15
+ # 将原始请求的头部信息转发到目标服务器
16
+ headers = dict(request.headers)
17
+
18
+ # 移除掉 Flask/Werkzeug 会默认修改的Headers
19
+ headers.pop('Host', None)
20
+ headers.pop('Content-Length', None)
21
+
22
+ # 使用 requests 发送经过构造的请求到目标服务器
23
+ resp = requests.request(
24
+ method=request.method,
25
+ url=f"{PROXY_TARGET}/{path}",
26
+ headers=headers,
27
+ data=request.get_data(),
28
+ cookies=request.cookies,
29
+ allow_redirects=False,
30
+ stream=True
31
+ )
32
 
33
+ # 创建一个生成器, 按块读取响应内容, 不需要一次性全部读入内存
34
+ def generate():
35
+ for chunk in resp.iter_content(chunk_size=4096):
36
+ yield chunk
37
 
38
+ # 将目标服务器的响应头转发回客户端
39
+ response_headers = [(name, value) for (name, value) in resp.raw.headers.items()]
 
 
 
 
 
 
 
 
 
40
 
41
+ # 使用 stream_with_context 包装响应内容生成器
42
+ response_stream = Response(stream_with_context(generate()), resp.status_code, response_headers)
43
 
44
+ return response_stream
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
+ if __name__ == '__main__':
48
+ app.run(debug=True,port=7860)