letterm commited on
Commit
197434d
·
verified ·
1 Parent(s): f1cb4c1

Update api_service.py

Browse files
Files changed (1) hide show
  1. api_service.py +296 -296
api_service.py CHANGED
@@ -1,297 +1,297 @@
1
- """
2
- API服务模块
3
- 处理所有API请求逻辑,包括聊天完成和Token管理
4
- """
5
- import json
6
- import time
7
- from datetime import datetime
8
- from typing import List, Dict, Any, Generator
9
- from loguru import logger
10
-
11
- from config import Config
12
- from utils import Utils
13
- from token_manager import MultiTokenManager
14
- from warp_client import WarpClient
15
- from request_converter import RequestConverter
16
- from model_mapper import ModelMapper
17
-
18
-
19
- class ApiService:
20
- """API服务类,处理所有业务逻辑"""
21
-
22
- def __init__(self):
23
- # 初始化Token管理器
24
- self.token_manager = MultiTokenManager()
25
-
26
- # 初始化Warp客户端
27
- self.warp_client = WarpClient(self.token_manager)
28
-
29
- logger.info("🚀 ApiService初始化完成")
30
-
31
- def authenticate_request(self, auth_header: str) -> bool:
32
- """验证API请求"""
33
- if not auth_header:
34
- return False
35
-
36
- token = Utils.extract_bearer_token(auth_header)
37
- if not token:
38
- return False
39
-
40
- return Utils.validate_api_key(token)
41
-
42
- def get_models(self) -> Dict[str, Any]:
43
- """获取支持的模型列表"""
44
- return ModelMapper.get_openai_models()
45
-
46
- def chat_completion(self, request_data: Dict[str, Any], stream: bool = False) -> Generator[str, None, None]:
47
- """处理聊天完成请求"""
48
- request_id = Utils.generate_request_id()
49
- # 解析请求
50
- openai_request = RequestConverter.parse_openai_request(request_data)
51
- model = openai_request.model
52
- messages = openai_request.messages
53
-
54
- logger.info(f"🎯 开始处理聊天请求 [ID: {request_id[:8]}] [模型: {model}] [流式: {stream}]")
55
- start_time = time.time()
56
-
57
- try:
58
- # 创建protobuf数据
59
- protobuf_data = self.warp_client.create_protobuf_data(messages, model)
60
- if not protobuf_data:
61
- error_msg = "创建请求数据失败"
62
- logger.error(f"❌ {error_msg} [ID: {request_id[:8]}]")
63
- yield self._create_error_response(error_msg, request_id)
64
- return
65
-
66
- # 发送请求并处理响应
67
- response_chunks = 0
68
- total_content = ""
69
-
70
- logger.success(f"🚀 开始接收响应 [ID: {request_id[:8]}]")
71
-
72
- for chunk_text in self.warp_client.send_request(protobuf_data):
73
- if chunk_text:
74
- response_chunks += 1
75
- total_content += chunk_text
76
-
77
- logger.debug(f"📦 响应块 #{response_chunks} [ID: {request_id[:8]}] [长度: {len(chunk_text)}]")
78
-
79
- if stream:
80
- # 流式响应
81
- chunk_response = self._create_stream_chunk(chunk_text, request_id)
82
- yield f"data: {json.dumps(chunk_response)}\n\n"
83
- else:
84
- # 非流式响应 - 等待完整内容
85
- continue
86
-
87
- # 处理响应结束
88
- end_time = time.time()
89
- duration = end_time - start_time
90
-
91
- if stream:
92
- # 发送结束标记
93
- final_chunk = self._create_stream_end_chunk(request_id)
94
- yield f"data: {json.dumps(final_chunk)}\n\n"
95
- yield "data: [DONE]\n\n"
96
-
97
- logger.success(f"✅ 流式响应完成 [ID: {request_id[:8]}] [块数: {response_chunks}] [耗时: {duration:.2f}s]")
98
- else:
99
- # 返回完整响应
100
- response = self._create_complete_response(total_content, request_id)
101
- yield response
102
-
103
- logger.success(f"✅ 完整响应完成 [ID: {request_id[:8]}] [长度: {len(total_content)}] [耗时: {duration:.2f}s]")
104
-
105
- except Exception as e:
106
- logger.error(f"❌ 聊天请求处理失败 [ID: {request_id[:8]}]: {e}")
107
- yield self._create_error_response(f"服务器内部错误: {str(e)}", request_id)
108
-
109
- def _create_stream_chunk(self, content: str, request_id: str) -> Dict[str, Any]:
110
- """创建流式响应块"""
111
- return {
112
- "id": f"chatcmpl-{request_id}",
113
- "object": "chat.completion.chunk",
114
- "created": int(time.time()),
115
- "model": "gemini-2.0-flash",
116
- "choices": [{
117
- "index": 0,
118
- "delta": {"content": content},
119
- "finish_reason": None
120
- }]
121
- }
122
-
123
- def _create_stream_end_chunk(self, request_id: str) -> Dict[str, Any]:
124
- """创建流式响应结束块"""
125
- return {
126
- "id": f"chatcmpl-{request_id}",
127
- "object": "chat.completion.chunk",
128
- "created": int(time.time()),
129
- "model": "gemini-2.0-flash",
130
- "choices": [{
131
- "index": 0,
132
- "delta": {},
133
- "finish_reason": "stop"
134
- }]
135
- }
136
-
137
- def _create_complete_response(self, content: str, request_id: str) -> Dict[str, Any]:
138
- """创建完整响应"""
139
- return {
140
- "id": f"chatcmpl-{request_id}",
141
- "object": "chat.completion",
142
- "created": int(time.time()),
143
- "model": "gemini-2.0-flash",
144
- "choices": [{
145
- "index": 0,
146
- "message": {
147
- "role": "assistant",
148
- "content": content
149
- },
150
- "finish_reason": "stop"
151
- }],
152
- "usage": {
153
- "prompt_tokens": 0,
154
- "completion_tokens": 0,
155
- "total_tokens": 0
156
- }
157
- }
158
-
159
- def _create_error_response(self, error_message: str, request_id: str) -> Dict[str, Any]:
160
- """创建错误响应"""
161
- return {
162
- "error": {
163
- "message": error_message,
164
- "type": "api_error",
165
- "code": "internal_error"
166
- },
167
- "id": request_id
168
- }
169
-
170
- def get_token_status(self) -> Dict[str, Any]:
171
- """获取Token状态"""
172
- try:
173
- status = self.token_manager.get_token_status()
174
- return {"success": True, **status}
175
- except Exception as e:
176
- logger.error(f"❌ 获取Token状态失败: {e}")
177
- return {"success": False, "message": str(e)}
178
-
179
- def add_tokens(self, tokens: List[str]) -> Dict[str, Any]:
180
- """添加Token"""
181
- try:
182
- success = self.token_manager.add_refresh_tokens(tokens)
183
- if success:
184
- valid_tokens = [t for t in tokens if Utils.validate_refresh_token_format(t)]
185
- return {
186
- "success": True,
187
- "message": "Token添加成功",
188
- "added_tokens": len(valid_tokens)
189
- }
190
- else:
191
- return {"success": False, "message": "没有有效的Token可添加"}
192
- except Exception as e:
193
- logger.error(f"❌ 添加Token失败: {e}")
194
- return {"success": False, "message": str(e)}
195
-
196
- def remove_refresh_token(self, refresh_token: str) -> Dict[str, Any]:
197
- """删除refresh token"""
198
- try:
199
- success = self.token_manager.remove_refresh_token(refresh_token)
200
- if success:
201
- return {"success": True, "message": "Token删除成功"}
202
- else:
203
- return {"success": False, "message": "Token不存在"}
204
- except Exception as e:
205
- logger.error(f"❌ 删除Token失败: {e}")
206
- return {"success": False, "message": str(e)}
207
-
208
- def refresh_all_tokens(self) -> Dict[str, Any]:
209
- """刷新所有Token"""
210
- try:
211
- self.token_manager.refresh_all_tokens()
212
- return {"success": True, "message": "Token刷新已开始"}
213
- except Exception as e:
214
- logger.error(f"❌ 刷新Token失败: {e}")
215
- return {"success": False, "message": str(e)}
216
-
217
- def export_refresh_tokens(self, super_admin_key: str) -> Dict[str, Any]:
218
- """导出refresh token内容(需要超级管理员密钥验证)"""
219
- try:
220
- # 验证超级管理员密钥
221
- if Config.require_super_admin_auth():
222
- if not super_admin_key or super_admin_key != Config.get_super_admin_key():
223
- return {"success": False, "message": "超级管理员密钥验证失败"}
224
-
225
- # 获取所有refresh token
226
- with self.token_manager.token_lock:
227
- refresh_tokens = list(self.token_manager.tokens.keys())
228
-
229
- if not refresh_tokens:
230
- return {"success": False, "message": "没有可导出的token"}
231
-
232
- # 创建分号分割的token字符串
233
- token_string = ";".join(refresh_tokens)
234
-
235
- # 生成建议的文件名(带时间戳)
236
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
237
- suggested_filename = f"refresh_tokens_export_{timestamp}.txt"
238
-
239
- logger.info(f"🔒 超级管理员请求导出 {len(refresh_tokens)} 个refresh token")
240
-
241
- return {
242
- "success": True,
243
- "message": f"准备导出 {len(refresh_tokens)} 个token",
244
- "content": token_string,
245
- "suggested_filename": suggested_filename,
246
- "token_count": len(refresh_tokens)
247
- }
248
-
249
- except Exception as e:
250
- logger.error(f"❌ 准备导出refresh token失败: {e}")
251
- return {"success": False, "message": f"导出失败: {str(e)}"}
252
-
253
- def batch_get_refresh_tokens(self, email_url_dict: Dict[str, str], max_workers: int = 5) -> Dict[str, Any]:
254
- """批量获取refresh token并自动创建用户"""
255
- try:
256
- from login_client import LoginClient
257
- login_client = LoginClient()
258
-
259
- # 传递token_manager参数,这样在获取refresh_token后会立即尝试创建用户
260
- results = login_client.batch_process_emails(email_url_dict, max_workers, self.token_manager)
261
-
262
- # 提取有效的token并添加到管理器
263
- valid_tokens = []
264
- for email, result in results.items():
265
- if result.get('refresh_token'):
266
- valid_tokens.append(result['refresh_token'])
267
-
268
- if valid_tokens:
269
- self.token_manager.add_refresh_tokens(valid_tokens)
270
- logger.info(f"✅ 批量获取并添加了 {len(valid_tokens)} 个有效token")
271
-
272
- return {
273
- 'success': True,
274
- 'results': results,
275
- 'total_count': len(email_url_dict),
276
- 'success_count': len(valid_tokens)
277
- }
278
-
279
- except Exception as e:
280
- logger.error(f"❌ 批量获取refresh token失败: {e}")
281
- return {'success': False, 'message': str(e)}
282
-
283
- def start_services(self):
284
- """启动后台服务"""
285
- try:
286
- self.token_manager.start_auto_refresh()
287
- logger.success("✅ 后台服务启动成功")
288
- except Exception as e:
289
- logger.error(f"❌ 启动后台服务失败: {e}")
290
-
291
- def stop_services(self):
292
- """停止后台服务"""
293
- try:
294
- self.token_manager.stop_auto_refresh()
295
- logger.info("⏹️ 后台服务已停止")
296
- except Exception as e:
297
  logger.error(f"❌ 停止后台服务失败: {e}")
 
1
+ """
2
+ API服务模块
3
+ 处理所有API请求逻辑,包括聊天完成和Token管理
4
+ """
5
+ import json
6
+ import time
7
+ from datetime import datetime
8
+ from typing import List, Dict, Any, Generator
9
+ from loguru import logger
10
+
11
+ from config import Config
12
+ from utils import Utils
13
+ from token_manager import MultiTokenManager
14
+ from warp_client import WarpClient
15
+ from request_converter import RequestConverter
16
+ from model_mapper import ModelMapper
17
+
18
+
19
+ class ApiService:
20
+ """API服务类,处理所有业务逻辑"""
21
+
22
+ def __init__(self):
23
+ # 初始化Token管理器
24
+ self.token_manager = MultiTokenManager()
25
+
26
+ # 初始化Warp客户端
27
+ self.warp_client = WarpClient(self.token_manager)
28
+
29
+ logger.info("🚀 ApiService初始化完成")
30
+
31
+ def authenticate_request(self, auth_header: str) -> bool:
32
+ """验证API请求"""
33
+ if not auth_header:
34
+ return False
35
+
36
+ token = Utils.extract_bearer_token(auth_header)
37
+ if not token:
38
+ return False
39
+
40
+ return Utils.validate_api_key(token)
41
+
42
+ def get_models(self) -> Dict[str, Any]:
43
+ """获取支持的模型列表"""
44
+ return ModelMapper.get_available_models()
45
+
46
+ def chat_completion(self, request_data: Dict[str, Any], stream: bool = False) -> Generator[str, None, None]:
47
+ """处理聊天完成请求"""
48
+ request_id = Utils.generate_request_id()
49
+ # 解析请求
50
+ openai_request = RequestConverter.parse_openai_request(request_data)
51
+ model = openai_request.model
52
+ messages = openai_request.messages
53
+
54
+ logger.info(f"🎯 开始处理聊天请求 [ID: {request_id[:8]}] [模型: {model}] [流式: {stream}]")
55
+ start_time = time.time()
56
+
57
+ try:
58
+ # 创建protobuf数据
59
+ protobuf_data = self.warp_client.create_protobuf_data(messages, model)
60
+ if not protobuf_data:
61
+ error_msg = "创建请求数据失败"
62
+ logger.error(f"❌ {error_msg} [ID: {request_id[:8]}]")
63
+ yield self._create_error_response(error_msg, request_id)
64
+ return
65
+
66
+ # 发送请求并处理响应
67
+ response_chunks = 0
68
+ total_content = ""
69
+
70
+ logger.success(f"🚀 开始接收响应 [ID: {request_id[:8]}]")
71
+
72
+ for chunk_text in self.warp_client.send_request(protobuf_data):
73
+ if chunk_text:
74
+ response_chunks += 1
75
+ total_content += chunk_text
76
+
77
+ logger.debug(f"📦 响应块 #{response_chunks} [ID: {request_id[:8]}] [长度: {len(chunk_text)}]")
78
+
79
+ if stream:
80
+ # 流式响应
81
+ chunk_response = self._create_stream_chunk(chunk_text, request_id)
82
+ yield f"data: {json.dumps(chunk_response)}\n\n"
83
+ else:
84
+ # 非流式响应 - 等待完整内容
85
+ continue
86
+
87
+ # 处理响应结束
88
+ end_time = time.time()
89
+ duration = end_time - start_time
90
+
91
+ if stream:
92
+ # 发送结束标记
93
+ final_chunk = self._create_stream_end_chunk(request_id)
94
+ yield f"data: {json.dumps(final_chunk)}\n\n"
95
+ yield "data: [DONE]\n\n"
96
+
97
+ logger.success(f"✅ 流式响应完成 [ID: {request_id[:8]}] [块数: {response_chunks}] [耗时: {duration:.2f}s]")
98
+ else:
99
+ # 返回完整响应
100
+ response = self._create_complete_response(total_content, request_id)
101
+ yield response
102
+
103
+ logger.success(f"✅ 完整响应完成 [ID: {request_id[:8]}] [长度: {len(total_content)}] [耗时: {duration:.2f}s]")
104
+
105
+ except Exception as e:
106
+ logger.error(f"❌ 聊天请求处理失败 [ID: {request_id[:8]}]: {e}")
107
+ yield self._create_error_response(f"服务器内部错误: {str(e)}", request_id)
108
+
109
+ def _create_stream_chunk(self, content: str, request_id: str) -> Dict[str, Any]:
110
+ """创建流式响应块"""
111
+ return {
112
+ "id": f"chatcmpl-{request_id}",
113
+ "object": "chat.completion.chunk",
114
+ "created": int(time.time()),
115
+ "model": "gemini-2.0-flash",
116
+ "choices": [{
117
+ "index": 0,
118
+ "delta": {"content": content},
119
+ "finish_reason": None
120
+ }]
121
+ }
122
+
123
+ def _create_stream_end_chunk(self, request_id: str) -> Dict[str, Any]:
124
+ """创建流式响应结束块"""
125
+ return {
126
+ "id": f"chatcmpl-{request_id}",
127
+ "object": "chat.completion.chunk",
128
+ "created": int(time.time()),
129
+ "model": "gemini-2.0-flash",
130
+ "choices": [{
131
+ "index": 0,
132
+ "delta": {},
133
+ "finish_reason": "stop"
134
+ }]
135
+ }
136
+
137
+ def _create_complete_response(self, content: str, request_id: str) -> Dict[str, Any]:
138
+ """创建完整响应"""
139
+ return {
140
+ "id": f"chatcmpl-{request_id}",
141
+ "object": "chat.completion",
142
+ "created": int(time.time()),
143
+ "model": "gemini-2.0-flash",
144
+ "choices": [{
145
+ "index": 0,
146
+ "message": {
147
+ "role": "assistant",
148
+ "content": content
149
+ },
150
+ "finish_reason": "stop"
151
+ }],
152
+ "usage": {
153
+ "prompt_tokens": 0,
154
+ "completion_tokens": 0,
155
+ "total_tokens": 0
156
+ }
157
+ }
158
+
159
+ def _create_error_response(self, error_message: str, request_id: str) -> Dict[str, Any]:
160
+ """创建错误响应"""
161
+ return {
162
+ "error": {
163
+ "message": error_message,
164
+ "type": "api_error",
165
+ "code": "internal_error"
166
+ },
167
+ "id": request_id
168
+ }
169
+
170
+ def get_token_status(self) -> Dict[str, Any]:
171
+ """获取Token状态"""
172
+ try:
173
+ status = self.token_manager.get_token_status()
174
+ return {"success": True, **status}
175
+ except Exception as e:
176
+ logger.error(f"❌ 获取Token状态失败: {e}")
177
+ return {"success": False, "message": str(e)}
178
+
179
+ def add_tokens(self, tokens: List[str]) -> Dict[str, Any]:
180
+ """添加Token"""
181
+ try:
182
+ success = self.token_manager.add_refresh_tokens(tokens)
183
+ if success:
184
+ valid_tokens = [t for t in tokens if Utils.validate_refresh_token_format(t)]
185
+ return {
186
+ "success": True,
187
+ "message": "Token添加成功",
188
+ "added_tokens": len(valid_tokens)
189
+ }
190
+ else:
191
+ return {"success": False, "message": "没有有效的Token可添加"}
192
+ except Exception as e:
193
+ logger.error(f"❌ 添加Token失败: {e}")
194
+ return {"success": False, "message": str(e)}
195
+
196
+ def remove_refresh_token(self, refresh_token: str) -> Dict[str, Any]:
197
+ """删除refresh token"""
198
+ try:
199
+ success = self.token_manager.remove_refresh_token(refresh_token)
200
+ if success:
201
+ return {"success": True, "message": "Token删除成功"}
202
+ else:
203
+ return {"success": False, "message": "Token不存在"}
204
+ except Exception as e:
205
+ logger.error(f"❌ 删除Token失败: {e}")
206
+ return {"success": False, "message": str(e)}
207
+
208
+ def refresh_all_tokens(self) -> Dict[str, Any]:
209
+ """刷新所有Token"""
210
+ try:
211
+ self.token_manager.refresh_all_tokens()
212
+ return {"success": True, "message": "Token刷新已开始"}
213
+ except Exception as e:
214
+ logger.error(f"❌ 刷新Token失败: {e}")
215
+ return {"success": False, "message": str(e)}
216
+
217
+ def export_refresh_tokens(self, super_admin_key: str) -> Dict[str, Any]:
218
+ """导出refresh token内容(需要超级管理员密钥验证)"""
219
+ try:
220
+ # 验证超级管理员密钥
221
+ if Config.require_super_admin_auth():
222
+ if not super_admin_key or super_admin_key != Config.get_super_admin_key():
223
+ return {"success": False, "message": "超级管理员密钥验证失败"}
224
+
225
+ # 获取所有refresh token
226
+ with self.token_manager.token_lock:
227
+ refresh_tokens = list(self.token_manager.tokens.keys())
228
+
229
+ if not refresh_tokens:
230
+ return {"success": False, "message": "没有可导出的token"}
231
+
232
+ # 创建分号分割的token字符串
233
+ token_string = ";".join(refresh_tokens)
234
+
235
+ # 生成建议的文件名(带时间戳)
236
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
237
+ suggested_filename = f"refresh_tokens_export_{timestamp}.txt"
238
+
239
+ logger.info(f"🔒 超级管理员请求导出 {len(refresh_tokens)} 个refresh token")
240
+
241
+ return {
242
+ "success": True,
243
+ "message": f"准备导出 {len(refresh_tokens)} 个token",
244
+ "content": token_string,
245
+ "suggested_filename": suggested_filename,
246
+ "token_count": len(refresh_tokens)
247
+ }
248
+
249
+ except Exception as e:
250
+ logger.error(f"❌ 准备导出refresh token失败: {e}")
251
+ return {"success": False, "message": f"导出失败: {str(e)}"}
252
+
253
+ def batch_get_refresh_tokens(self, email_url_dict: Dict[str, str], max_workers: int = 5) -> Dict[str, Any]:
254
+ """批量获取refresh token并自动创建用户"""
255
+ try:
256
+ from login_client import LoginClient
257
+ login_client = LoginClient()
258
+
259
+ # 传递token_manager参数,这样在获取refresh_token后会立即尝试创建用户
260
+ results = login_client.batch_process_emails(email_url_dict, max_workers, self.token_manager)
261
+
262
+ # 提取有效的token并添加到管理器
263
+ valid_tokens = []
264
+ for email, result in results.items():
265
+ if result.get('refresh_token'):
266
+ valid_tokens.append(result['refresh_token'])
267
+
268
+ if valid_tokens:
269
+ self.token_manager.add_refresh_tokens(valid_tokens)
270
+ logger.info(f"✅ 批量获取并添加了 {len(valid_tokens)} 个有效token")
271
+
272
+ return {
273
+ 'success': True,
274
+ 'results': results,
275
+ 'total_count': len(email_url_dict),
276
+ 'success_count': len(valid_tokens)
277
+ }
278
+
279
+ except Exception as e:
280
+ logger.error(f"❌ 批量获取refresh token失败: {e}")
281
+ return {'success': False, 'message': str(e)}
282
+
283
+ def start_services(self):
284
+ """启动后台服务"""
285
+ try:
286
+ self.token_manager.start_auto_refresh()
287
+ logger.success("✅ 后台服务启动成功")
288
+ except Exception as e:
289
+ logger.error(f"❌ 启动后台服务失败: {e}")
290
+
291
+ def stop_services(self):
292
+ """停止后台服务"""
293
+ try:
294
+ self.token_manager.stop_auto_refresh()
295
+ logger.info("⏹️ 后台服务已停止")
296
+ except Exception as e:
297
  logger.error(f"❌ 停止后台服务失败: {e}")