0
votes

I am using flask_login manager to login a user as described here, however, when the user_loader callback is called, flask throws error: TypeError: unbound method get_id() must be called with User instance as first argument (got int instance instead) I have tried replacing User.get_id(user_id) with a database call to return the object within the user_loader callback, however, an error is generated AttributeError: 'Query' object has no attribute 'is_authenticated'. Any light on what I'm doing wrong here will help.

Flask Packages For LoginManager

from flask_login import LoginManager, 
UserMixin, login_user, login_required, 
logout_user, current_user

My User Class:

class User(Base, UserMixin):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
username = Column(String(32), index=True)
hash_password = Column(String(80))

def is_authenticated(self):
    return True

def is_active(self):
    return True

def is_anonymous(self):
    return False

def get_id(self):
    return unicode(self.id)

def __repr__(self):
    return '<User %r>' % (self.username)

@property
def serializable(self):
    return {'id': self.id, 'username': self.username}

My Login functions

app = Flask(__name__)
bootstrap = Bootstrap(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

@app.route('/login/', methods=['GET', 'POST'])
def showLogin():
form = LoginForm()
if form.validate_on_submit():

    user = session.query(User).filter_by(username=form.username.data).first()

    if user is not None:

        if check_password_hash(user.hash_password, form.password.data):
            login_session['username'] = user.username
            login_session['user_id'] = user.id
            login_user(user)

            flash('Your Are Now Logged In')
            return redirect(url_for('showCatalog'))
        else:
            flash('Username Or Password Invalid')
            return redirect(url_for('showLogin'))

return render_template('login.html', form=form)

@login_manager.user_loader
def load_user(user_id):
   return User.get_id(user_id)

Stack Trace

File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1997, in 
__call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1985, in 
wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1540, in 
handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1982, in 
wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1614, in 
full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1517, in 
handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1612, in 
full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1598, in 
dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python2.7/dist-packages/flask_login/utils.py", line 
259, in decorated_view
elif not current_user.is_authenticated:
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 347, 
in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 306, 
in _get_current_object
return self.__local()
File "/usr/local/lib/python2.7/dist-packages/flask_login/utils.py", line 26, 
in <lambda>
current_user = LocalProxy(lambda: _get_user())
File "/usr/local/lib/python2.7/dist-packages/flask_login/utils.py", line 
335, in _get_user
current_app.login_manager._load_user()
File "/usr/local/lib/python2.7/dist-packages/flask_login/login_manager.py", 
line 359, in _load_user
Open an interactive python shell in this framereturn self.reload_user()
File "/usr/local/lib/python2.7/dist-packages/flask_login/login_manager.py", 
line 321, in reload_user
user = self.user_callback(user_id)
File "/vagrant/finalproject/webserver.py", line 193, in load_user
return User.get_id(user_id)
TypeError: unbound method get_id() must be called with User instance as 
first argument (got int instance instead)
2

2 Answers

2
votes

The get_id method of User expect a User instance as first and only argument:

def get_id(self):

And you are passing the user_id to it. That the explanation of the exception.

But I you meant to get the user object from the db ? try:

User.query.filter(User.id == user_id).first()
1
votes

This resolved my issue for both errors.

User loader(Modified)

@login_manager.user_loader
  def load_user(user_id):
  user = session.query(User).filter_by(id=user_id).first()
  if user is not None:
     return user
  else:
     return None