| |
| """ |
| API Key 相关的工具函数。 |
| """ |
| import httpx |
| import json |
| import logging |
| from typing import Optional |
| import secrets |
| import string |
|
|
| |
| logger = logging.getLogger("my_logger") |
|
|
| |
| def generate_random_key(length: int = 40) -> str: |
| """ |
| 生成一个指定长度的安全随机字符串,可用作 API Key。 |
| 默认长度为 40。 |
| |
| Args: |
| length (int): 生成的 Key 的长度。 |
| |
| Returns: |
| str: 生成的随机 Key 字符串。 |
| """ |
| |
| alphabet = string.ascii_letters + string.digits |
| |
| random_key = ''.join(secrets.choice(alphabet) for _ in range(length)) |
| |
| |
| logger.debug(f"生成了新的随机 Key (长度: {length})") |
| return random_key |
|
|
| |
| async def test_api_key(api_key: str, http_client: httpx.AsyncClient) -> bool: |
| """ |
| 异步测试单个 Gemini API 密钥的有效性。 |
| 通过尝试调用一个轻量级的、通常不需要特殊权限的 API 端点(例如列出可用模型) |
| 来验证密钥是否能够成功认证并与 Gemini API 通信。 |
| 使用传入的共享 httpx.AsyncClient 实例以提高效率。 |
| |
| Args: |
| api_key (str): 需要测试的 Gemini API 密钥字符串。 |
| http_client (httpx.AsyncClient): 用于发送 HTTP 请求的共享异步客户端实例。 |
| |
| Returns: |
| bool: 如果 API 密钥测试通过(能够成功调用 API 并获得预期响应),则返回 True; |
| 否则(包括网络错误、超时、认证失败、响应格式错误等),返回 False。 |
| """ |
| |
| test_url = f"https://generativelanguage.googleapis.com/v1beta/models?key={api_key}" |
| try: |
| |
| response = await http_client.get(test_url, timeout=10.0) |
|
|
| |
| if response.status_code == 200: |
| |
| try: |
| data = response.json() |
| |
| if "models" in data and isinstance(data["models"], list): |
| |
| logger.info(f"测试 Key {api_key[:10]}... 成功。") |
| return True |
| else: |
| |
| logger.warning(f"测试 Key {api_key[:10]}... 成功 (状态码 200),但响应 JSON 格式不符合预期: {data}") |
| return False |
| except json.JSONDecodeError: |
| |
| logger.warning(f"测试 Key {api_key[:10]}... 成功 (状态码 200),但无法解析响应体为 JSON。") |
| return False |
| else: |
| |
| error_detail = f"状态码: {response.status_code}" |
| try: |
| |
| error_json = response.json() |
| |
| error_detail += f", 错误: {error_json.get('error', {}).get('message', '未知 API 错误')}" |
| except json.JSONDecodeError: |
| |
| error_detail += f", 响应体: {response.text}" |
| |
| logger.warning(f"测试 Key {api_key[:10]}... 失败 ({error_detail})") |
| return False |
|
|
| except httpx.TimeoutException: |
| |
| logger.warning(f"测试 Key {api_key[:10]}... 请求超时。") |
| return False |
|
|
| except httpx.RequestError as e: |
| |
| logger.warning(f"测试 Key {api_key[:10]}... 时发生网络请求错误: {e}") |
| return False |
|
|
| except Exception as e: |
| |
| logger.error(f"测试 Key {api_key[:10]}... 时发生未知错误: {e}", exc_info=True) |
| return False |
|
|
| |
| |
| |
| |
| |
| |
|
|