From 6adae569be3d8be5ee861938cb0a03858750db45 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Mon, 27 Apr 2026 15:40:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20/api/v1/sessions=20?= =?UTF-8?q?500=20=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 validate_ip_and_apikey 装饰器无法获取 Request 对象的问题: 原代码通过遍历 args 查找 Request 对象,但 FastAPI 端点使用 Pydantic 模型作为参数时找不到 Request,导致装饰器跳过验证并可能引发异常。 改为显式声明 request: Request 作为 wrapper 的第一个参数,由 FastAPI 自动注入。 - 增强 ensure_user_hermes_env 的错误处理: 添加 try/except 包裹,检查 BASE_HERMES_PATH 是否存在, 将未处理的异常转为带详细信息的 HTTPException(500)。 --- main.py | 67 ++++++++++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/main.py b/main.py index 20f1af8..20e6417 100644 --- a/main.py +++ b/main.py @@ -165,22 +165,7 @@ def validate_ip_and_apikey(): """Decorator to validate IP and API key for protected endpoints""" def decorator(func): @wraps(func) - async def wrapper(*args, **kwargs): - # Extract request object (assuming it's the first argument after self) - request = None - for arg in args: - if isinstance(arg, Request): - request = arg - break - - if request is None: - # Try to find request in kwargs - request = kwargs.get('request') - - if request is None: - # If no request object found, skip validation - return await func(*args, **kwargs) - + async def wrapper(request: Request, *args, **kwargs): # IP validation if config['security']['enable_ip_check']: client_ip = get_real_ip(request) @@ -241,27 +226,37 @@ def get_user_hermes_path(user_id: str) -> str: def ensure_user_hermes_env(user_id: str): """Ensure user has isolated Hermes environment""" - user_base_path = get_user_hermes_path(user_id) - user_hermes_path = os.path.join(user_base_path, "hermes-agent") - user_dot_hermes = os.path.join(user_base_path, ".hermes") - - if not os.path.exists(user_hermes_path): - os.makedirs(user_base_path, exist_ok=True, mode=0o700) - shutil.copytree( - BASE_HERMES_PATH, - user_hermes_path, - dirs_exist_ok=True, - ignore=shutil.ignore_patterns('.git', '__pycache__', '*.pyc', '.venv', 'web_dist') - ) - os.makedirs(user_dot_hermes, exist_ok=True, mode=0o700) - venv_link = os.path.join(user_hermes_path, '.venv') - if not os.path.exists(venv_link): - os.symlink( - os.path.join(BASE_HERMES_PATH, '.venv'), - venv_link + try: + user_base_path = get_user_hermes_path(user_id) + user_hermes_path = os.path.join(user_base_path, "hermes-agent") + user_dot_hermes = os.path.join(user_base_path, ".hermes") + + if not os.path.exists(user_hermes_path): + os.makedirs(user_base_path, exist_ok=True, mode=0o700) + if not os.path.exists(BASE_HERMES_PATH): + raise FileNotFoundError(f"Base Hermes path not found: {BASE_HERMES_PATH}") + shutil.copytree( + BASE_HERMES_PATH, + user_hermes_path, + dirs_exist_ok=True, + ignore=shutil.ignore_patterns('.git', '__pycache__', '*.pyc', '.venv', 'web_dist') ) - - return user_hermes_path + os.makedirs(user_dot_hermes, exist_ok=True, mode=0o700) + venv_link = os.path.join(user_hermes_path, '.venv') + if not os.path.exists(venv_link): + os.symlink( + os.path.join(BASE_HERMES_PATH, '.venv'), + venv_link + ) + + return user_hermes_path + except HTTPException: + raise + except Exception as e: + print(f"ERROR: Failed to ensure user Hermes env for {user_id}: {e}") + import traceback + traceback.print_exc() + raise HTTPException(status_code=500, detail=f"Failed to initialize user environment: {str(e)}") @app.get("/health") @validate_ip_and_apikey()