开发者

TypeError: 'str' object is not callable when using CherryPy 3.2 Basic Authentication

My site configures CherryPy by way of a configuration file. In the configuration file I am trying to setup basic authentication. I have specified the fully qualified path to a "checkpassword" function. But I'm getting an error about the tools.auth_basic.checkpassword line.

Most of the samples online, do not use a config file. So it's making things more difficult.

My config file:

[/]
tools.auth_basic.on = True
tools.auth_basic.realm = "some site"
tools.auth_basic.checkpassword = "Infrastructure.App.Authentication.FindPassword"

My startweb.py file:

import ...
...

cherrypy.tree.mount(DesktopRootController(), "/", "auth.conf")

cherrypy.engine.start()
cherrypy.engine.block()

The error message:

[10/Sep/2011:12:51:29] HTTP Traceback (most recent call last):
 File "lib.zip\cherrypy\_cprequest.py", line 642, in respond
   self.hooks.run('before_handler')
 File "lib.zip\cherrypy\_cprequest.py", line 97, in run
   hook()
 File "lib.zip\cherrypy\_cprequest.py", line 57, in __call__
   return self.callback(**self.kwargs)
 File "lib.zip\cherrypy\lib\auth_basic.py", line 76, in basic_auth
   if checkpassword(realm, username, password):
TypeError: 'str' object is not callable

My "callable" is defined here:

import cherrypy

class Authentication:
    def FindPassword(realm, username, password):
        print realm
        print username
        print password
        return "password"

And this is some of the "App" class:

from Authentication import Authentication

class App:
    def __call__(self):
        return self

    def __init__(self):
        self._authentication = Authentication

    @property
    def Authentication(self):
        return _aut开发者_开发问答hentication


CherryPy config options are always regular python values. If you want to describe a module variable, you have to find a way to import it into the config file.

[/]
tools.auth_basic.on = True
tools.auth_basic.realm = "some site"
tools.auth_basic.checkpassword = __import__("Infrastructure.App.Authentication").App.Authentication.FindPassword

Edit: It looks like cherrypy's option parser chokes on the import keyword; you'll have to use the even longer, even less DRY form like this.

Edit2: the next problem you have is a missing self parameter. Change your authentication class to this:

class Authentication:
    def FindPassword(self, realm, username, password):
        #            ^^^^^
        print realm
        print username
        print password
        return "password"


The solution!

First, fix the config file like this. Remove the quotes from the function name:

tools.auth_basic.checkpassword =  Infrastructure.App.Authentication.FindPassword

Second, add the @staticmethod keyword to the checkpassword function:

@staticmethod
def FindPassword(realm, username, password):
    print realm
    print username
    print password
    return "password"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜