Python/Flask: AttributeError: 'RequestContext' object has no attribute 'login' (when assigning to session['username'])

Issue

I am trying to set the session['username'] attribute in Flask. I am using Blueprints. My directory structure looks like this (truncated some irrelevant subdirectories):

├───app
│   ├───forum
│   │   ├───static
│   │   └───templates
│   ├───googleutils
│   ├───home
│   ├───login
│   ├───profile
│   ├───register
│   ├───static
│   └───templates
└───env

I am working in a virtual environment.

In the app directory, I have an __init__.py which contains the following:

from flask import Flask

def create_app():
    app = Flask(__name__, instance_relative_config=False)
    app.secret_key = 'who_cares_about_security' # ignore bad secret, placeholder

    with app.app_context():
        # Register blueprints here, truncated for clarity

        from .login import login
        app.register_blueprint(login.login_bp)

        return app

In the login directory, I have this login.py:

from flask import Blueprint, render_template, request, session, redirect, url_for
import app.googleutils.utils as googleutil

login_bp = Blueprint(
    'login_bp', __name__,
    template_folder='templates',
    static_folder='static'
)


@login_bp.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == "POST":
        # process login request
        username = request.form["username"]
        password = request.form["password"]
        user = googleutil.find_user(username, password)

        if user:
            session["username"] = username
            return redirect(url_for('home_bp.home'))

        return render_template('login.html') #placeholder
    else:
        return render_template('login.html')

When the user visits /login, they fill out a username/password form, which I grab via POST. This is checked against a list of entities stored on Google Datastore. If a username/password match is found, I attempt to assign the session['username'] attribute to the username. However, this gives me an error: AttributeError: 'RequestContext' object has no attribute 'login'.

This is the stack trace:

Traceback (most recent call last):
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\NAME\Desktop\PROJECT\env\login\login.py", line 20, in login
    session["username"] = username
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\werkzeug\local.py", line 350, in __setitem__
    self._get_current_object()[key] = value
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\werkzeug\local.py", line 306, in _get_current_object
    return self.__local()
  File "C:\Users\NAME\Desktop\PROJECT\env\Lib\site-packages\flask\globals.py", line 39, in _lookup_req_object
    return getattr(top, name)
AttributeError: 'RequestContext' object has no attribute 'login'

I’m not sure what I am doing wrong. Looking in flask’s globals.py I find these lines which mention the "login" attribute:

# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "login"))
g = LocalProxy(partial(_lookup_app_object, "g"))

But I don’t know what to do from here.

Uncommenting the line session["username"] = username fixes the error, and the RHS variable username is definitely not empty.

Thank you.

Solution

Flask’s globals.py should look like this:

session = LocalProxy(partial(_lookup_req_object, "session"))

As per the flask source code. That line has never used the string "login", in flask’s history. I am not sure why your system has it as such, but changing it back to "session" should fix your issue.

Answered By – Sam Nolan

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published