tanbushi commited on
Commit
e4007c6
·
1 Parent(s): b06c450
.gitignore ADDED
File without changes
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.11
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
__pycache__/app.cpython-311.pyc ADDED
Binary file (866 Bytes). View file
 
app.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # uvicorn app:app --host 0.0.0.0 --port 7860
2
+
3
+ from fastapi import FastAPI
4
+ from routers import v1, v2, openai
5
+
6
+ app = FastAPI()
7
+
8
+ app.include_router(v1.router, prefix="/v1")
9
+ app.include_router(v2.router, prefix="/v2")
10
+ app.include_router(openai.router, prefix="/openai")
11
+
12
+ @app.get("/")
13
+ def greet_json():
14
+ return {"Hello": "World!"}
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ requests
routers/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from . import v1, v2, openai
routers/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (247 Bytes). View file
 
routers/__pycache__/openai.cpython-311.pyc ADDED
Binary file (11.5 kB). View file
 
routers/__pycache__/v1.cpython-311.pyc ADDED
Binary file (4.01 kB). View file
 
routers/__pycache__/v2.cpython-311.pyc ADDED
Binary file (534 Bytes). View file
 
routers/openai.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Request, HTTPException
2
+ from pydantic import BaseModel
3
+ from typing import List, Optional
4
+
5
+ router = APIRouter()
6
+
7
+ # 定义请求和响应的数据模型
8
+
9
+ class ChatCompletionMessage(BaseModel):
10
+ """
11
+ 聊天完成消息的数据模型
12
+ role: 消息的角色,例如 "user" 或 "assistant"
13
+ content: 消息的内容
14
+ """
15
+ role: str
16
+ content: str
17
+
18
+ class ChatCompletionRequest(BaseModel):
19
+ """
20
+ 聊天完成请求的数据模型
21
+ model: 使用的模型名称
22
+ messages: 消息列表,包含用户的输入和助手的回复
23
+ max_tokens: (可选) 生成的最大 token 数
24
+ temperature: (可选) 控制生成文本的随机性
25
+ """
26
+ model: str
27
+ messages: List[ChatCompletionMessage]
28
+ max_tokens: Optional[int] = None
29
+ temperature: Optional[float] = None
30
+
31
+ class ChatCompletionChoice(BaseModel):
32
+ """
33
+ 聊天完成选项的数据模型
34
+ index: 选项的索引
35
+ message: 聊天完成消息
36
+ finish_reason: 完成的原因,例如 "stop"
37
+ """
38
+ index: int
39
+ message: ChatCompletionMessage
40
+ finish_reason: str
41
+
42
+ class ChatCompletionUsage(BaseModel):
43
+ """
44
+ 聊天完成用量的数据模型
45
+ prompt_tokens: prompt 使用的 token 数
46
+ completion_tokens: 完成生成的 token 数
47
+ total_tokens: 总共使用的 token 数
48
+ """
49
+ prompt_tokens: int
50
+ completion_tokens: int
51
+ total_tokens: int
52
+
53
+ class ChatCompletionResponse(BaseModel):
54
+ """
55
+ 聊天完成响应的数据模型
56
+ id: 响应的 ID
57
+ object: 响应的对象类型,例如 "chat.completion"
58
+ created: 响应的创建时间戳
59
+ model: 使用的模型名称
60
+ choices: 选项列表
61
+ usage: 用量信息
62
+ """
63
+ id: str
64
+ object: str
65
+ created: int
66
+ model: str
67
+ choices: List[ChatCompletionChoice]
68
+ usage: ChatCompletionUsage
69
+
70
+ class CompletionRequest(BaseModel):
71
+ """
72
+ 文本生成请求的数据模型
73
+ model: 使用的模型名称
74
+ prompt: 输入的 prompt
75
+ max_tokens: (可选) 生成的最大 token 数
76
+ temperature: (可选) 控制生成文本的随机性
77
+ """
78
+ model: str
79
+ prompt: str
80
+ max_tokens: Optional[int] = None
81
+ temperature: Optional[float] = None
82
+
83
+ class CompletionChoice(BaseModel):
84
+ """
85
+ 文本生成选项的数据模型
86
+ index: 选项的索引
87
+ text: 生成的文本
88
+ finish_reason: 完成的原因,例如 "stop"
89
+ """
90
+ index: int
91
+ text: str
92
+ finish_reason: str
93
+
94
+ class CompletionUsage(BaseModel):
95
+ """
96
+ 文本生成用量的数据模型
97
+ prompt_tokens: prompt 使用的 token 数
98
+ completion_tokens: 完成生成的 token 数
99
+ total_tokens: 总共使用的 token 数
100
+ """
101
+ prompt_tokens: int
102
+ completion_tokens: int
103
+ total_tokens: int
104
+
105
+ class CompletionResponse(BaseModel):
106
+ """
107
+ 文本生成响应的数据模型
108
+ id: 响应的 ID
109
+ object: 响应的对象类型,例如 "text_completion"
110
+ created: 响应的创建时间戳
111
+ model: 使用的模型名称
112
+ choices: 选项列表
113
+ usage: 用量信息
114
+ """
115
+ id: str
116
+ object: str
117
+ created: int
118
+ model: str
119
+ choices: List[CompletionChoice]
120
+ usage: CompletionUsage
121
+
122
+ class EmbeddingRequest(BaseModel):
123
+ """
124
+ Embedding 请求的数据模型
125
+ model: 使用的模型名称
126
+ input: 输入的文本
127
+ """
128
+ model: str
129
+ input: str
130
+
131
+ class EmbeddingData(BaseModel):
132
+ """
133
+ Embedding 数据的数据模型
134
+ index: 数据的索引
135
+ embedding: Embedding 向量
136
+ """
137
+ index: int
138
+ embedding: List[float]
139
+
140
+ class EmbeddingResponse(BaseModel):
141
+ """
142
+ Embedding 响应的数据模型
143
+ object: 响应的对象类型,例如 "list"
144
+ data: Embedding 数据列表
145
+ model: 使用的模型名称
146
+ usage: 用量信息,例如 {"prompt_tokens": 8, "total_tokens": 8}
147
+ """
148
+ object: str
149
+ data: List[EmbeddingData]
150
+ model: str
151
+ usage: dict # Example: {"prompt_tokens": 8, "total_tokens": 8}
152
+
153
+ class RerankRequest(BaseModel):
154
+ """
155
+ Rerank 请求的数据模型
156
+ model: 使用的模型名称
157
+ query: 查询文本
158
+ documents: 文档列表
159
+ max_chunks: (可选) 最大 chunk 数
160
+ """
161
+ model: str
162
+ query: str
163
+ documents: List[str]
164
+ max_chunks: Optional[int] = None
165
+
166
+ class RerankResponse(BaseModel):
167
+ """
168
+ Rerank 响应的数据模型
169
+ model: 使用的模型名称
170
+ results: Rerank 结果列表,例如 [{"index": 0, "relevance_score": 0.9}]
171
+ """
172
+ model: str
173
+ results: List[dict] # Example: [{"index": 0, "relevance_score": 0.9}]
174
+
175
+
176
+ # 实现 endpoint
177
+
178
+ @router.post("/chat/completions")
179
+ async def chat_completions(request: ChatCompletionRequest):
180
+ """
181
+ 聊天完成 endpoint
182
+ 接收 ChatCompletionRequest,返回 ChatCompletionResponse
183
+ """
184
+ # Implement chat completion logic here
185
+ # This is a placeholder, replace with actual implementation
186
+ print(f"Received chat completion request: {request}")
187
+ if not isinstance(request, ChatCompletionRequest):
188
+ raise HTTPException(status_code=400, detail="Invalid request format")
189
+
190
+ response = ChatCompletionResponse(
191
+ id="chatcmpl-xxxxxxxxxxxxxxxxxxxxxxxx",
192
+ object="chat.completion",
193
+ created=1629750000,
194
+ model=request.model,
195
+ choices=[
196
+ ChatCompletionChoice(
197
+ index=0,
198
+ message=ChatCompletionMessage(
199
+ role="assistant",
200
+ content="This is a dummy response for chat completion.",
201
+ ),
202
+ finish_reason="stop",
203
+ )
204
+ ],
205
+ usage=ChatCompletionUsage(
206
+ prompt_tokens=10, completion_tokens=20, total_tokens=30
207
+ ),
208
+ )
209
+ return response
210
+
211
+ @router.post("/completions")
212
+ async def completions(request: CompletionRequest):
213
+ """
214
+ 文本生成 endpoint
215
+ 接收 CompletionRequest,返回 CompletionResponse
216
+ """
217
+ # Implement text generation logic here
218
+ # This is a placeholder, replace with actual implementation
219
+ print(f"Received completion request: {request}")
220
+ response = CompletionResponse(
221
+ id="cmpl-xxxxxxxxxxxxxxxxxxxxxxxx",
222
+ object="text_completion",
223
+ created=1629750000,
224
+ model=request.model,
225
+ choices=[
226
+ CompletionChoice(
227
+ index=0,
228
+ text="This is a dummy response for text completion.",
229
+ finish_reason="stop",
230
+ )
231
+ ],
232
+ usage=CompletionUsage(
233
+ prompt_tokens=10, completion_tokens=20, total_tokens=30
234
+ ),
235
+ )
236
+ return response
237
+
238
+ @router.post("/embeddings")
239
+ async def embeddings(request: EmbeddingRequest):
240
+ """
241
+ Embedding endpoint
242
+ 接收 EmbeddingRequest,返回 EmbeddingResponse
243
+ """
244
+ # Implement embedding logic here
245
+ # This is a placeholder, replace with actual implementation
246
+ print(f"Received embedding request: {request}")
247
+ response = EmbeddingResponse(
248
+ object="list",
249
+ data=[
250
+ EmbeddingData(
251
+ index=0,
252
+ embedding=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
253
+ )
254
+ ],
255
+ model=request.model,
256
+ usage={"prompt_tokens": 8, "total_tokens": 8},
257
+ )
258
+ return response
259
+
260
+ @router.post("/rerank")
261
+ async def rerank(request: RerankRequest):
262
+ """
263
+ Rerank endpoint
264
+ 接收 RerankRequest,返回 RerankResponse
265
+ """
266
+ # Implement rerank logic here
267
+ # This is a placeholder, replace with actual implementation
268
+ print(f"Received rerank request: {request}")
269
+ response = RerankResponse(
270
+ model=request.model,
271
+ results=[{"index": 0, "relevance_score": 0.9}],
272
+ )
273
+ return response
routers/v1.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from fastapi import APIRouter, HTTPException, Request
3
+ from pydantic import BaseModel
4
+ from typing import List, Optional
5
+ import random
6
+ import string
7
+
8
+ router = APIRouter()
9
+
10
+ def generate_chatcmpl_id():
11
+ characters = string.ascii_letters + string.digits
12
+ return "chatcmpl-" + ''.join(random.choice(characters) for i in range(29))
13
+
14
+ # Define data models for request and response
15
+
16
+ class ChatCompletionMessage(BaseModel):
17
+ role: str
18
+ content: str
19
+
20
+ class ChatCompletionRequest(BaseModel):
21
+ model: str
22
+ messages: List[ChatCompletionMessage]
23
+ max_tokens: Optional[int] = None
24
+ temperature: Optional[float] = None
25
+
26
+ class ChatCompletionChoice(BaseModel):
27
+ index: int
28
+ message: ChatCompletionMessage
29
+ finish_reason: str
30
+
31
+ class ChatCompletionUsage(BaseModel):
32
+ prompt_tokens: int
33
+ completion_tokens: int
34
+ total_tokens: int
35
+
36
+ class ChatCompletionResponse(BaseModel):
37
+ id: str
38
+ object: str
39
+ created: int
40
+ model: str
41
+ choices: List[ChatCompletionChoice]
42
+ usage: ChatCompletionUsage
43
+
44
+ @router.post("/chat/completions")
45
+ async def chat_completions(chat_request: ChatCompletionRequest, request: Request):
46
+ """
47
+ 聊天完成 endpoint,调用 Gemini API
48
+ """
49
+ headers = dict(request.headers)
50
+ print(headers)
51
+ return "hh"
52
+ gemini_api_url = "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions" # 需要验证 URL 的正确性
53
+ auth_header = request.headers.get("Authorization")
54
+ headers = {"Content-Type": "application/json"}
55
+ if auth_header:
56
+ headers["Authorization"] = auth_header
57
+
58
+ try:
59
+ response = requests.post(gemini_api_url, headers=headers, json=chat_request.model_dump())
60
+ response.raise_for_status() # 检查请求是否成功
61
+
62
+ # 将 Gemini API 的响应转换为 ChatCompletionResponse
63
+ gemini_response = response.json()
64
+ print(f"Gemini API response: {gemini_response}") # 打印 Gemini API 的响应
65
+
66
+ chat_completion_response = ChatCompletionResponse(
67
+ id=generate_chatcmpl_id(),
68
+ object="chat.completion",
69
+ created=gemini_response.get("created", 1629750000),
70
+ model=chat_request.model,
71
+ choices=[
72
+ ChatCompletionChoice(
73
+ index=i,
74
+ message=ChatCompletionMessage(
75
+ role=choice.get("message", {}).get("role", "assistant"),
76
+ content=choice.get("message", {}).get("content", "This is a dummy response from Gemini."),
77
+ ),
78
+ finish_reason=choice.get("finish_reason", "stop"),
79
+ )
80
+ for i, choice in enumerate(gemini_response.get("choices", []))
81
+ ],
82
+ usage=ChatCompletionUsage(
83
+ prompt_tokens=gemini_response.get("usage", {}).get("prompt_tokens", 0),
84
+ completion_tokens=gemini_response.get("usage", {}).get("completion_tokens", 0),
85
+ total_tokens=gemini_response.get("usage", {}).get("total_tokens", 0),
86
+ ),
87
+ )
88
+ return chat_completion_response
89
+ except requests.exceptions.RequestException as e:
90
+ raise HTTPException(status_code=500, detail=str(e))
91
+
92
+ @router.get("/")
93
+ def greet_v1():
94
+ return {"version": "v1", "message": "Hello, World!"}
routers/v2.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter
2
+
3
+ router = APIRouter()
4
+
5
+ @router.get("/")
6
+ def greet_v2():
7
+ return {"version": "v2", "message": "Hello, World! This is version 2."}
程序开发笔记.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # 程序开发笔记
2
+
3
+ 1. 主文件为 app.py
4
+ 2. 以版本作为路由路径,将版本对应的路由放到 routers 文件夹下,routers/v1.py、routers/v2.py