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"
精彩评论