mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
fix: 修复 mypy 类型检查错误并升级到 Python 3.14
主要变更: - 修复 1483 个 mypy 类型检查错误 - 添加缺失的类型注解 (Any, Callable, Session 等) - 修复隐式 Optional 类型 (param: Type = None -> param: Type | None = None) - 修复 __new__ 单例模式返回类型 - 添加 type: ignore 注释处理第三方库类型问题 - 更新 pyproject.toml 依赖到 Python 3.14 兼容版本 - 更新 mypy/black 配置为 Python 3.14
This commit is contained in:
@@ -88,7 +88,7 @@ _LAZY_IMPORTS = {
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(name: str):
|
||||
def __getattr__(name: str) -> None:
|
||||
"""延迟导入以避免循环依赖"""
|
||||
if name in _LAZY_IMPORTS:
|
||||
module_path, attr_name = _LAZY_IMPORTS[name]
|
||||
|
||||
@@ -18,6 +18,7 @@ Chat Adapter 通用基类
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
import time
|
||||
import traceback
|
||||
from abc import abstractmethod
|
||||
@@ -129,7 +130,7 @@ class ChatAdapterBase(ApiAdapter):
|
||||
def __init__(self, allowed_api_formats: list[str] | None = None):
|
||||
self.allowed_api_formats = allowed_api_formats or [self.FORMAT_ID]
|
||||
|
||||
async def handle(self, context: ApiRequestContext):
|
||||
async def handle(self, context: ApiRequestContext) -> Any:
|
||||
"""处理 Chat API 请求"""
|
||||
http_request = context.request
|
||||
user = context.user
|
||||
@@ -262,14 +263,14 @@ class ChatAdapterBase(ApiAdapter):
|
||||
def _create_handler(
|
||||
self,
|
||||
*,
|
||||
db,
|
||||
user,
|
||||
api_key,
|
||||
db: Session,
|
||||
user: Any,
|
||||
api_key: Any,
|
||||
request_id: str,
|
||||
client_ip: str,
|
||||
user_agent: str,
|
||||
start_time: float,
|
||||
):
|
||||
) -> Any:
|
||||
"""创建 Handler 实例 - 子类可覆盖"""
|
||||
return self.HANDLER_CLASS(
|
||||
db=db,
|
||||
@@ -305,7 +306,7 @@ class ChatAdapterBase(ApiAdapter):
|
||||
return merged
|
||||
|
||||
@abstractmethod
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
|
||||
"""
|
||||
验证请求体 - 子类必须实现
|
||||
|
||||
@@ -318,7 +319,7 @@ class ChatAdapterBase(ApiAdapter):
|
||||
"""
|
||||
pass
|
||||
|
||||
def _extract_message_count(self, payload: dict[str, Any], request_obj) -> int:
|
||||
def _extract_message_count(self, payload: dict[str, Any], request_obj: Any) -> int:
|
||||
"""
|
||||
提取消息数量 - 子类可覆盖
|
||||
|
||||
@@ -329,7 +330,7 @@ class ChatAdapterBase(ApiAdapter):
|
||||
messages = request_obj.messages
|
||||
return len(messages) if isinstance(messages, list) else 0
|
||||
|
||||
def _build_audit_metadata(self, payload: dict[str, Any], request_obj) -> dict[str, Any]:
|
||||
def _build_audit_metadata(self, payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
|
||||
"""
|
||||
构建审计日志元数据 - 子类可覆盖
|
||||
"""
|
||||
@@ -351,9 +352,9 @@ class ChatAdapterBase(ApiAdapter):
|
||||
self,
|
||||
e: Exception,
|
||||
*,
|
||||
db,
|
||||
user,
|
||||
api_key,
|
||||
db: Session,
|
||||
user: Any,
|
||||
api_key: Any,
|
||||
model: str,
|
||||
stream: bool,
|
||||
start_time: float,
|
||||
@@ -422,9 +423,9 @@ class ChatAdapterBase(ApiAdapter):
|
||||
self,
|
||||
e: Exception,
|
||||
*,
|
||||
db,
|
||||
user,
|
||||
api_key,
|
||||
db: Session,
|
||||
user: Any,
|
||||
api_key: Any,
|
||||
model: str,
|
||||
stream: bool,
|
||||
start_time: float,
|
||||
@@ -710,7 +711,7 @@ def register_adapter(adapter_class: type[ChatAdapterBase]) -> type[ChatAdapterBa
|
||||
return adapter_class
|
||||
|
||||
|
||||
def _ensure_adapters_loaded():
|
||||
def _ensure_adapters_loaded() -> None:
|
||||
"""确保所有 Adapter 已被加载(触发注册)"""
|
||||
global _ADAPTERS_LOADED
|
||||
if _ADAPTERS_LOADED:
|
||||
|
||||
@@ -19,6 +19,8 @@ Chat Handler Base - Chat API 格式的通用基类
|
||||
- StreamTelemetryRecorder: 统计记录(Usage、Audit、Candidate)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
@@ -15,12 +15,15 @@ CLI Adapter 通用基类
|
||||
- 可选覆盖 compute_total_input_context() 自定义总输入上下文计算
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import traceback
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException, Request
|
||||
from sqlalchemy.orm import Session
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from src.api.base.adapter import ApiAdapter, ApiMode
|
||||
@@ -124,7 +127,7 @@ class CliAdapterBase(ApiAdapter):
|
||||
"""
|
||||
return get_adapter_protected_keys(cls._get_api_format())
|
||||
|
||||
async def handle(self, context: ApiRequestContext):
|
||||
async def handle(self, context: ApiRequestContext) -> Any:
|
||||
"""处理 CLI API 请求"""
|
||||
http_request = context.request
|
||||
user = context.user
|
||||
@@ -332,9 +335,9 @@ class CliAdapterBase(ApiAdapter):
|
||||
self,
|
||||
e: Exception,
|
||||
*,
|
||||
db,
|
||||
user,
|
||||
api_key,
|
||||
db: Session,
|
||||
user: Any,
|
||||
api_key: Any,
|
||||
model: str,
|
||||
stream: bool,
|
||||
start_time: float,
|
||||
@@ -403,9 +406,9 @@ class CliAdapterBase(ApiAdapter):
|
||||
self,
|
||||
e: Exception,
|
||||
*,
|
||||
db,
|
||||
user,
|
||||
api_key,
|
||||
db: Session,
|
||||
user: Any,
|
||||
api_key: Any,
|
||||
model: str,
|
||||
stream: bool,
|
||||
start_time: float,
|
||||
@@ -748,7 +751,7 @@ def register_cli_adapter(adapter_class: type[CliAdapterBase]) -> type[CliAdapter
|
||||
return adapter_class
|
||||
|
||||
|
||||
def _ensure_cli_adapters_loaded():
|
||||
def _ensure_cli_adapters_loaded() -> None:
|
||||
"""确保所有 CLI Adapter 已被加载(触发注册)"""
|
||||
global _CLI_ADAPTERS_LOADED
|
||||
if _CLI_ADAPTERS_LOADED:
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
5. 流式平滑输出
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import codecs
|
||||
import json
|
||||
|
||||
@@ -4,6 +4,8 @@ Claude Chat Adapter - 基于 ChatAdapterBase 的 Claude Chat API 适配器
|
||||
处理 /v1/messages 端点的 Claude Chat 格式请求。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
@@ -96,7 +98,7 @@ class ClaudeChatAdapter(ChatAdapterBase):
|
||||
"""
|
||||
return input_tokens + cache_creation_input_tokens + cache_read_input_tokens
|
||||
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
|
||||
"""验证请求体"""
|
||||
try:
|
||||
if not isinstance(original_request_body, dict):
|
||||
@@ -124,7 +126,7 @@ class ClaudeChatAdapter(ChatAdapterBase):
|
||||
)
|
||||
return request
|
||||
|
||||
def _build_audit_metadata(self, _payload: dict[str, Any], request_obj) -> dict[str, Any]:
|
||||
def _build_audit_metadata(self, _payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
|
||||
"""构建 Claude Chat 特定的审计元数据"""
|
||||
role_counts: dict[str, int] = {}
|
||||
for message in request_obj.messages:
|
||||
@@ -201,7 +203,7 @@ class ClaudeChatAdapter(ChatAdapterBase):
|
||||
# build_request_body 使用基类实现,通过 format_conversion_registry 自动转换 OPENAI -> CLAUDE
|
||||
|
||||
|
||||
def build_claude_adapter(x_app_header: str | None):
|
||||
def build_claude_adapter(x_app_header: str | None) -> Any:
|
||||
"""根据 x-app 头部构造 Chat 或 Claude Code 适配器。"""
|
||||
if x_app_header and x_app_header.lower() == "cli":
|
||||
from src.api.handlers.claude_cli.adapter import ClaudeCliAdapter
|
||||
@@ -228,7 +230,7 @@ class ClaudeTokenCountAdapter(ApiAdapter):
|
||||
return authorization.replace("Bearer ", "")
|
||||
return None
|
||||
|
||||
async def handle(self, context: ApiRequestContext):
|
||||
async def handle(self, context: ApiRequestContext) -> Any:
|
||||
payload = context.ensure_json_body()
|
||||
|
||||
try:
|
||||
|
||||
@@ -4,6 +4,8 @@ Claude CLI Adapter - 基于通用 CLI Adapter 基类的简化实现
|
||||
继承 CliAdapterBase,只需配置 FORMAT_ID 和 HANDLER_CLASS。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
@@ -91,7 +91,7 @@ class GeminiChatAdapter(ChatAdapterBase):
|
||||
"""
|
||||
return original_request_body.copy()
|
||||
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
|
||||
"""验证请求体"""
|
||||
path_params = path_params or {}
|
||||
is_stream = path_params.get("stream", False)
|
||||
@@ -124,14 +124,14 @@ class GeminiChatAdapter(ChatAdapterBase):
|
||||
request.stream = is_stream
|
||||
return request
|
||||
|
||||
def _extract_message_count(self, payload: dict[str, Any], request_obj) -> int:
|
||||
def _extract_message_count(self, payload: dict[str, Any], request_obj: Any) -> int:
|
||||
"""提取消息数量"""
|
||||
contents = payload.get("contents", [])
|
||||
if hasattr(request_obj, "contents"):
|
||||
contents = request_obj.contents
|
||||
return len(contents) if isinstance(contents, list) else 0
|
||||
|
||||
def _build_audit_metadata(self, payload: dict[str, Any], request_obj) -> dict[str, Any]:
|
||||
def _build_audit_metadata(self, payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
|
||||
"""构建 Gemini Chat 特定的审计元数据"""
|
||||
role_counts: dict[str, int] = {}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Gemini Chat Handler
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from starlette.requests import Request
|
||||
from typing import Any
|
||||
|
||||
from src.api.handlers.base.chat_handler_base import ChatHandlerBase
|
||||
@@ -102,7 +103,7 @@ class GeminiChatHandler(ChatHandlerBase):
|
||||
return str(path_params["model"])
|
||||
return "unknown"
|
||||
|
||||
async def _convert_request(self, request):
|
||||
async def _convert_request(self, request: Request) -> None:
|
||||
"""
|
||||
将请求转换为 Gemini 格式的 Pydantic 对象
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ Gemini CLI Adapter - 基于通用 CLI Adapter 基类的实现
|
||||
继承 CliAdapterBase,处理 Gemini CLI 格式的请求。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
@@ -4,6 +4,8 @@ OpenAI Chat Adapter - 基于 ChatAdapterBase 的 OpenAI Chat API 适配器
|
||||
处理 /v1/chat/completions 端点的 OpenAI Chat 格式请求。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
@@ -37,7 +39,7 @@ class OpenAIChatAdapter(ChatAdapterBase):
|
||||
def __init__(self, allowed_api_formats: list[str] | None = None):
|
||||
super().__init__(allowed_api_formats or ["OPENAI"])
|
||||
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
|
||||
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
|
||||
"""验证请求体"""
|
||||
if not isinstance(original_request_body, dict):
|
||||
return self._error_response(
|
||||
@@ -66,7 +68,7 @@ class OpenAIChatAdapter(ChatAdapterBase):
|
||||
max_tokens=original_request_body.get("max_tokens"),
|
||||
)
|
||||
|
||||
def _build_audit_metadata(self, payload: dict[str, Any], request_obj) -> dict[str, Any]:
|
||||
def _build_audit_metadata(self, payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
|
||||
"""构建 OpenAI Chat 特定的审计元数据"""
|
||||
role_counts = {}
|
||||
for message in request_obj.messages:
|
||||
|
||||
@@ -5,6 +5,9 @@ OpenAI Chat Handler - 基于通用 Chat Handler 基类的简化实现
|
||||
代码量从原来的 ~1315 行减少到 ~100 行。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from starlette.requests import Request
|
||||
from typing import Any
|
||||
|
||||
from src.api.handlers.base.chat_handler_base import ChatHandlerBase
|
||||
@@ -63,7 +66,7 @@ class OpenAIChatHandler(ChatHandlerBase):
|
||||
result["model"] = mapped_model
|
||||
return result
|
||||
|
||||
async def _convert_request(self, request):
|
||||
async def _convert_request(self, request: Request) -> None:
|
||||
"""
|
||||
将请求转换为 OpenAI 格式的 Pydantic 对象
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ OpenAI CLI Adapter - 基于通用 CLI Adapter 基类的简化实现
|
||||
继承 CliAdapterBase,只需配置 FORMAT_ID 和 HANDLER_CLASS。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
Reference in New Issue
Block a user