Search code examples
pythoncherrypy

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 _authentication

Solution

  • 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"