Upload 10 files
Browse files- app/main.py +3 -52
- app/utils.py +0 -3
app/main.py
CHANGED
@@ -17,18 +17,9 @@ import logging
|
|
17 |
logging.getLogger("uvicorn").disabled = True
|
18 |
logging.getLogger("uvicorn.access").disabled = True
|
19 |
|
20 |
-
# 全局统计变量
|
21 |
-
today_calls = 0
|
22 |
-
total_calls = 0
|
23 |
-
|
24 |
# 配置 logger
|
25 |
logger = logging.getLogger("my_logger")
|
26 |
logger.setLevel(logging.DEBUG)
|
27 |
-
# 添加带时间戳的格式
|
28 |
-
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
29 |
-
handler = logging.StreamHandler()
|
30 |
-
handler.setFormatter(formatter)
|
31 |
-
logger.addHandler(handler)
|
32 |
|
33 |
def translate_error(message: str) -> str:
|
34 |
if "quota exceeded" in message.lower():
|
@@ -111,12 +102,6 @@ key_manager = APIKeyManager() # 实例化 APIKeyManager,栈会在 __init__ 中
|
|
111 |
current_api_key = key_manager.get_available_key()
|
112 |
|
113 |
|
114 |
-
def reset_daily_counter():
|
115 |
-
global today_calls
|
116 |
-
today_calls = 0
|
117 |
-
log_msg = format_log_message('INFO', "每日调用计数器已重置")
|
118 |
-
logger.info(log_msg)
|
119 |
-
|
120 |
def switch_api_key():
|
121 |
global current_api_key
|
122 |
key = key_manager.get_available_key() # get_available_key 会处理栈的逻辑
|
@@ -158,9 +143,6 @@ async def startup_event():
|
|
158 |
# MAX_RETRIES = len(key_manager.api_keys)
|
159 |
log_msg = format_log_message('INFO', f"最大重试次数设置为:{len(key_manager.api_keys)}") # 添加日志
|
160 |
logger.info(log_msg)
|
161 |
-
# 添加每日计数器重置任务
|
162 |
-
scheduler.add_job(reset_daily_counter, 'cron', hour=0, minute=0)
|
163 |
-
|
164 |
if key_manager.api_keys:
|
165 |
all_models = await GeminiClient.list_available_models(key_manager.api_keys[0])
|
166 |
GeminiClient.AVAILABLE_MODELS = [model.replace(
|
@@ -189,24 +171,11 @@ async def verify_password(request: Request):
|
|
189 |
|
190 |
async def process_request(chat_request: ChatCompletionRequest, http_request: Request, request_type: Literal['stream', 'non-stream']):
|
191 |
global current_api_key
|
192 |
-
# 获取请求详细信息
|
193 |
-
client_ip = http_request.client.host if http_request.client else 'unknown'
|
194 |
-
method = http_request.method
|
195 |
-
path = http_request.url.path
|
196 |
-
|
197 |
protect_from_abuse(
|
198 |
http_request, MAX_REQUESTS_PER_MINUTE, MAX_REQUESTS_PER_DAY_PER_IP)
|
199 |
if chat_request.model not in GeminiClient.AVAILABLE_MODELS:
|
200 |
error_msg = "无效的模型"
|
201 |
-
extra_log = {
|
202 |
-
'request_type': request_type,
|
203 |
-
'model': chat_request.model,
|
204 |
-
'status_code': 400,
|
205 |
-
'error_message': error_msg,
|
206 |
-
'client_ip': client_ip,
|
207 |
-
'method': method,
|
208 |
-
'path': path
|
209 |
-
}
|
210 |
log_msg = format_log_message('ERROR', error_msg, extra=extra_log)
|
211 |
logger.error(log_msg)
|
212 |
raise HTTPException(
|
@@ -223,27 +192,11 @@ async def process_request(chat_request: ChatCompletionRequest, http_request: Req
|
|
223 |
current_api_key = key_manager.get_available_key() # 每次循环开始都获取新的 key, 栈逻辑在 get_available_key 中处理
|
224 |
|
225 |
if current_api_key is None: # 检查是否获取到 API 密钥
|
226 |
-
log_msg_no_key = format_log_message('WARNING', "没有可用的 API 密钥,跳过本次尝试", extra={
|
227 |
-
'request_type': request_type,
|
228 |
-
'model': chat_request.model,
|
229 |
-
'status_code': 'N/A',
|
230 |
-
'client_ip': client_ip,
|
231 |
-
'method': method,
|
232 |
-
'path': path
|
233 |
-
})
|
234 |
logger.warning(log_msg_no_key)
|
235 |
break # 如果没有可用密钥,跳出循环
|
236 |
|
237 |
-
extra_log = {
|
238 |
-
'key': current_api_key[:8],
|
239 |
-
'request_type': request_type,
|
240 |
-
'model': chat_request.model,
|
241 |
-
'status_code': 'N/A',
|
242 |
-
'error_message': '',
|
243 |
-
'client_ip': client_ip,
|
244 |
-
'method': method,
|
245 |
-
'path': path
|
246 |
-
}
|
247 |
log_msg = format_log_message('INFO', f"第 {attempt}/{retry_attempts} 次尝试 ... 使用密钥: {current_api_key[:8]}...", extra=extra_log)
|
248 |
logger.info(log_msg)
|
249 |
|
@@ -411,8 +364,6 @@ async def root():
|
|
411 |
<p class="status">服务运行中</p>
|
412 |
<p>可用API密钥数量: {len(key_manager.api_keys)}</p>
|
413 |
<p>可用模型数量: {len(GeminiClient.AVAILABLE_MODELS)}</p>
|
414 |
-
<p>今日调用次数: {today_calls}</p>
|
415 |
-
<p>累计调用次数: {total_calls}</p>
|
416 |
</div>
|
417 |
|
418 |
<div class="info-box">
|
|
|
17 |
logging.getLogger("uvicorn").disabled = True
|
18 |
logging.getLogger("uvicorn.access").disabled = True
|
19 |
|
|
|
|
|
|
|
|
|
20 |
# 配置 logger
|
21 |
logger = logging.getLogger("my_logger")
|
22 |
logger.setLevel(logging.DEBUG)
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
def translate_error(message: str) -> str:
|
25 |
if "quota exceeded" in message.lower():
|
|
|
102 |
current_api_key = key_manager.get_available_key()
|
103 |
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
def switch_api_key():
|
106 |
global current_api_key
|
107 |
key = key_manager.get_available_key() # get_available_key 会处理栈的逻辑
|
|
|
143 |
# MAX_RETRIES = len(key_manager.api_keys)
|
144 |
log_msg = format_log_message('INFO', f"最大重试次数设置为:{len(key_manager.api_keys)}") # 添加日志
|
145 |
logger.info(log_msg)
|
|
|
|
|
|
|
146 |
if key_manager.api_keys:
|
147 |
all_models = await GeminiClient.list_available_models(key_manager.api_keys[0])
|
148 |
GeminiClient.AVAILABLE_MODELS = [model.replace(
|
|
|
171 |
|
172 |
async def process_request(chat_request: ChatCompletionRequest, http_request: Request, request_type: Literal['stream', 'non-stream']):
|
173 |
global current_api_key
|
|
|
|
|
|
|
|
|
|
|
174 |
protect_from_abuse(
|
175 |
http_request, MAX_REQUESTS_PER_MINUTE, MAX_REQUESTS_PER_DAY_PER_IP)
|
176 |
if chat_request.model not in GeminiClient.AVAILABLE_MODELS:
|
177 |
error_msg = "无效的模型"
|
178 |
+
extra_log = {'request_type': request_type, 'model': chat_request.model, 'status_code': 400, 'error_message': error_msg}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
log_msg = format_log_message('ERROR', error_msg, extra=extra_log)
|
180 |
logger.error(log_msg)
|
181 |
raise HTTPException(
|
|
|
192 |
current_api_key = key_manager.get_available_key() # 每次循环开始都获取新的 key, 栈逻辑在 get_available_key 中处理
|
193 |
|
194 |
if current_api_key is None: # 检查是否获取到 API 密钥
|
195 |
+
log_msg_no_key = format_log_message('WARNING', "没有可用的 API 密钥,跳过本次尝试", extra={'request_type': request_type, 'model': chat_request.model, 'status_code': 'N/A'})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
logger.warning(log_msg_no_key)
|
197 |
break # 如果没有可用密钥,跳出循环
|
198 |
|
199 |
+
extra_log = {'key': current_api_key[:8], 'request_type': request_type, 'model': chat_request.model, 'status_code': 'N/A', 'error_message': ''}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
log_msg = format_log_message('INFO', f"第 {attempt}/{retry_attempts} 次尝试 ... 使用密钥: {current_api_key[:8]}...", extra=extra_log)
|
201 |
logger.info(log_msg)
|
202 |
|
|
|
364 |
<p class="status">服务运行中</p>
|
365 |
<p>可用API密钥数量: {len(key_manager.api_keys)}</p>
|
366 |
<p>可用模型数量: {len(GeminiClient.AVAILABLE_MODELS)}</p>
|
|
|
|
|
367 |
</div>
|
368 |
|
369 |
<div class="info-box">
|
app/utils.py
CHANGED
@@ -34,9 +34,6 @@ def format_log_message(level, message, extra=None):
|
|
34 |
'model': extra.get('model', 'N/A'),
|
35 |
'status_code': extra.get('status_code', 'N/A'),
|
36 |
'error_message': extra.get('error_message', ''),
|
37 |
-
'client_ip': extra.get('client_ip', 'N/A'),
|
38 |
-
'method': extra.get('method', 'N/A'),
|
39 |
-
'path': extra.get('path', 'N/A'),
|
40 |
'message': message
|
41 |
}
|
42 |
log_format = LOG_FORMAT_DEBUG if DEBUG else LOG_FORMAT_NORMAL
|
|
|
34 |
'model': extra.get('model', 'N/A'),
|
35 |
'status_code': extra.get('status_code', 'N/A'),
|
36 |
'error_message': extra.get('error_message', ''),
|
|
|
|
|
|
|
37 |
'message': message
|
38 |
}
|
39 |
log_format = LOG_FORMAT_DEBUG if DEBUG else LOG_FORMAT_NORMAL
|