统一凭证管理器 所有存储操作通过storage_adapter进行
| 13 | from src.storage_adapter import get_storage_adapter |
| 14 | |
| 15 | class CredentialManager: |
| 16 | """ |
| 17 | 统一凭证管理器 |
| 18 | 所有存储操作通过storage_adapter进行 |
| 19 | """ |
| 20 | |
| 21 | def __init__(self): |
| 22 | # 核心状态 |
| 23 | self._initialized = False |
| 24 | self._storage_adapter = None |
| 25 | |
| 26 | # 并发控制(简化) |
| 27 | # 后端数据库自行处理并发,credential_manager 不再使用本地锁 |
| 28 | |
| 29 | async def _ensure_initialized(self): |
| 30 | """确保管理器已初始化(内部使用)""" |
| 31 | if not self._initialized or self._storage_adapter is None: |
| 32 | await self.initialize() |
| 33 | |
| 34 | async def initialize(self): |
| 35 | """初始化凭证管理器""" |
| 36 | if self._initialized and self._storage_adapter is not None: |
| 37 | return |
| 38 | |
| 39 | # 初始化统一存储适配器 |
| 40 | self._storage_adapter = await get_storage_adapter() |
| 41 | self._initialized = True |
| 42 | |
| 43 | async def close(self): |
| 44 | """清理资源""" |
| 45 | log.debug("Closing credential manager...") |
| 46 | self._initialized = False |
| 47 | log.debug("Credential manager closed") |
| 48 | |
| 49 | async def get_valid_credential( |
| 50 | self, mode: str = "geminicli", model_name: Optional[str] = None |
| 51 | ) -> Optional[Tuple[str, Dict[str, Any]]]: |
| 52 | """ |
| 53 | 获取有效的凭证 - 随机负载均衡版 |
| 54 | 每次随机选择一个可用的凭证(未禁用、未冷却、符合preview要求) |
| 55 | 如果刷新失败会自动禁用失效凭证并重试获取下一个可用凭证 |
| 56 | |
| 57 | Args: |
| 58 | mode: 凭证模式 ("geminicli" 或 "antigravity") |
| 59 | model_name: 完整模型名,用于模型级冷却检查和preview筛选 |
| 60 | - geminicli: 完整模型名 |
| 61 | - 包含 "preview" 的模型只能使用 preview=True 的凭证 |
| 62 | - 不包含 "preview" 的模型优先使用 preview=False 的凭证 |
| 63 | - antigravity: 完整模型名(如 "gemini-2.0-flash-exp") |
| 64 | """ |
| 65 | await self._ensure_initialized() |
| 66 | |
| 67 | # 最多重试3次 |
| 68 | max_retries = 3 |
| 69 | for attempt in range(max_retries): |
| 70 | result = await self._storage_adapter._backend.get_next_available_credential( |
| 71 | mode=mode, model_name=model_name |
| 72 | ) |