无法在 cherrpy 应用程序(站点树)的导入 sub-class 中调用装饰器

Can't call a decorator within the imported sub-class of a cherrpy application (site tree)

我正在使用 cherrypy 作为网络服务器,我想在返回页面之前检查用户的 logged-in 状态。这适用于主应用程序 class(在 site.py 中)中的方法,但是当我在网页树中更深一层的 class 中的方法上调用相同的装饰函数时会出错(在单独的文件中)。

validate_user() 是用作装饰器的函数。它要么将用户传递到页面,要么将他们发送到 401 受限页面,作为 cherrypy.Tool,如下所示:

from user import validate_user
cherrypy.tools.validate_user = cherrypy.Tool('before_handler', validate_user)

我通过将 sub-classes 的实例相应地分配为变量,将站点的不同部分附加到主 site.py 文件的应用程序 class:

from user import UserAuthentication

class Root:
    user = UserAuthentication() # maps user/login, user/register, user/logout, etc
    admin = Admin()
    api = Api()

    @cherrypy.expose
    @cherrypy.tools.validate_user()
    def how_to(self, **kw):
        from other_stuff import how_to_page
        return how_to_page(kw) 

但是,当我尝试在管理或 Api 或分析部分中使用 validate_user() 时,这不起作用。这些在单独的文件中。

import cherrypy

class Analyze:
    @cherrypy.expose
    @cherrypy.tools.validate_user() #### THIS LINE GIVES ERROR ####
    def explore(self, *args, **kw): # @addkw(fetch=['uid'])
        import explore
        kw['uid'] = cherrypy.session.get('uid',-1)
        return explore.explorer(args, kw)

错误是 cherrypy.tools 没有 validate_user 函数或方法。但我在 site.py 中分配的其他内容确实出现在 cherrypy here 中。为什么我不能在作为我的整体站点地图一部分的单独文件中使用此工具?

如果这是相关的,validate_user() 函数只需查看 cherrypy.request.cookie,找到 'session_token' 值,并将其与我们的数据库进行比较,如果ID 匹配。

抱歉,我不知道 Analyze() 和 Api() 以及 User() 页面是子classes,还是嵌套的classes,还是扩展方法, 还是什么。所以我不能给它一个准确的标题。我是否需要以某种方式将 parent class 传递给他们?

这里的问题是 Python 在导入过程中处理除 function/method 主体之外的所有内容。因此,在 site.py 中,当您 import user(或 from user import <anything>)时,会导致所有 user 模块在 之前 被处理Python 解释器已经到达 validate_user 工具的定义,包括试图通过值(而不是通过引用)访问该工具的装饰器。

CherryPy 有另一种机制,用于使用配置装饰函数,该配置将在这些处理程序上启用工具。代替 @cherrypy.tools.validate_user,使用:

@cherrypy.config(**{"tools.validate_user.on": True})

这个装饰器之所以有效,是因为它不需要从 cherrypy.tools 访问 validate_user 来将自身安装在处理程序上,而是将 CherryPy 配置为稍后在调用处理程序时将该工具安装在处理程序上.

如果该 class 上的所有方法都需要该工具,您可以在 class 本身上使用该配置装饰器。

您也可以在服务器配置中为给定端点启用该工具,如其他问题中所述。