|
|
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 |