|
|
import random
|
|
|
import re
|
|
|
import os
|
|
|
import logging
|
|
|
from datetime import datetime, timedelta
|
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
from app.utils.logging import format_log_message
|
|
|
|
|
|
logger = logging.getLogger("my_logger")
|
|
|
|
|
|
class APIKeyManager:
|
|
|
def __init__(self):
|
|
|
self.api_keys = re.findall(
|
|
|
r"AIzaSy[a-zA-Z0-9_-]{33}", os.environ.get('GEMINI_API_KEYS', ""))
|
|
|
self.key_stack = []
|
|
|
self._reset_key_stack()
|
|
|
|
|
|
|
|
|
self.scheduler = BackgroundScheduler()
|
|
|
self.scheduler.start()
|
|
|
self.tried_keys_for_request = set()
|
|
|
|
|
|
def _reset_key_stack(self):
|
|
|
"""创建并随机化密钥栈"""
|
|
|
shuffled_keys = self.api_keys[:]
|
|
|
random.shuffle(shuffled_keys)
|
|
|
self.key_stack = shuffled_keys
|
|
|
|
|
|
|
|
|
def get_available_key(self):
|
|
|
"""从栈顶获取密钥,栈空时重新生成 (修改后)"""
|
|
|
while self.key_stack:
|
|
|
key = self.key_stack.pop()
|
|
|
|
|
|
if key not in self.tried_keys_for_request:
|
|
|
self.tried_keys_for_request.add(key)
|
|
|
return key
|
|
|
|
|
|
if not self.api_keys:
|
|
|
log_msg = format_log_message('ERROR', "没有配置任何 API 密钥!")
|
|
|
logger.error(log_msg)
|
|
|
return None
|
|
|
|
|
|
self._reset_key_stack()
|
|
|
|
|
|
|
|
|
while self.key_stack:
|
|
|
key = self.key_stack.pop()
|
|
|
|
|
|
if key not in self.tried_keys_for_request:
|
|
|
self.tried_keys_for_request.add(key)
|
|
|
return key
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
def show_all_keys(self):
|
|
|
log_msg = format_log_message('INFO', f"当前可用API key个数: {len(self.api_keys)} ")
|
|
|
logger.info(log_msg)
|
|
|
for i, api_key in enumerate(self.api_keys):
|
|
|
log_msg = format_log_message('INFO', f"API Key{i}: {api_key[:8]}...{api_key[-3:]}")
|
|
|
logger.info(log_msg)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def reset_tried_keys_for_request(self):
|
|
|
"""在新的请求尝试时重置已尝试的 key 集合"""
|
|
|
self.tried_keys_for_request = set()
|
|
|
|
|
|
async def test_api_key(api_key: str) -> bool:
|
|
|
"""
|
|
|
测试 API 密钥是否有效。
|
|
|
"""
|
|
|
try:
|
|
|
import httpx
|
|
|
url = "https://generativelanguage.googleapis.com/v1beta/models?key={}".format(api_key)
|
|
|
async with httpx.AsyncClient() as client:
|
|
|
response = await client.get(url)
|
|
|
response.raise_for_status()
|
|
|
return True
|
|
|
except Exception:
|
|
|
return False |