Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting attributes in flask login current user for later access

I am trying to figure out a way to store recommendations for each user on a website so that when a user logs in the recommendations can be collected once and don't need to be updated until the user rates something new.

I thought a nice way to do this would be to store the recommendations in the User class, but it appears that when I try to access this attribute later the values are no longer there. To compound this issue, I found that from view to view the current_user address changes.

Example User class:

class User(UserMixin):
    def __init__(self, user_doc):
        self.username = user_doc['Username']
        self.userid = user_doc['User Id']
        self.recommendations = []

    def get_recs(self):
        self.recommendations = app.config['MODEL'].predict_all(self.userid)

Example views.py:

@APP.route('/', methods=['GET'])
def index():
    """Render the homepage."""
    if current_user.is_authenticated:
        if current_user.recommendations == []:
            current_user.get_recs()
    return render_template('index.html')

@APP.route('/recommend', methods=['POST', 'GET'])
@login_required
def recommend():
    recs = get_recommendations(current_user)
    return render_template('recommend.html', recs=recs[:10])

If I login and go through the homepage, current_user.recommendations get filled as expected. However, if I then navigate to /recommend and place a breakpoint before recs = get_recommendations(current_user) I find that current_user.recommendations is again an empty list. Is this the expected behavior of current_user and if so what is the proper way to store user attributes to prevent repeated calculation.

Thanks in advance for any help.

Edit

Apparently I didn't explain my problem thoroughly enough and it seemed similar to How to user g user global in flask. However, I read that question and it is not in fact in any way similar.

The problem:

My model is moderately complex and requires > 0.1 s to predict all of the recommendations for a user. It seems to me that structuring the website in a way that each time a user navigates to /recommend the recommendations must be calculated is wasteful and could given enough requests, slow down the server.

The solution:

In order to circumvent this problem I thought that calculating the recommendations once upon login and subsequently after new ratings are added would reduce the volume of predictions the server would need to calculate, thus improving performance of the server and the time necessary for loading the recommendations page for each user.

However, I can't seem to set an attribute in the existing current_user object in one view that is then available in another view.

The question:

Is there a way to set attribute values for the current_user object within a view, such that they are accessible to other views?

like image 250
Grr Avatar asked Jun 22 '17 15:06

Grr


People also ask

What is the use of is login in flask?

Is. Flask-Login. Flask-Loginis a dope library that handles all aspects of user management, including user sign-ups, encrypting passwords, handling sessions, and securing parts of our app behind login walls. Flask-Login also happens to play nicely with other Flask libraries we’re already familiar with!

How to login using cookie-based authentication in flask-login?

Flask-login uses Cookie-based Authentication. When the client logins via his credentials, Flask creates a session containing the user ID and then sends the session ID to the user via a cookie, using which he can log in and out as and when required. First we need to install the Flask-Login

How does flask work?

When the client logins via his credentials, Flask creates a session containing the user ID and then sends the session ID to the user via a cookie, using which he can log in and out as and when required. Now that it’s installed, let’s move into the coding part!

How to create a user model in flask-login?

The most notable tidbit for creating a User model is a nifty shortcut from Flask-Login called the UserMixin. UserMixinis a helper provided by the Flask-Login library to provide boilerplate methods necessary for managing users.


2 Answers

It's common to use a property for it:

class User(UserMixin):
    def __init__(self, user_doc):
        self.username = user_doc['Username']

    @property
    def recommendations(self):
        return do_some_stuff()

Then current_user.recommendations would return the results of the do_some_stuff() logic.

like image 181
Doobeh Avatar answered Sep 27 '22 17:09

Doobeh


It seems to me that current_user is being reloaded every time based on id initially provided.

Without resolving problem in originally desired way, I (as python newbie) suggest you do the trick:

from flask import session

session['data_variable_name'] = 'somedata'

And access session from places you need.

like image 24
TEH EMPRAH Avatar answered Sep 27 '22 18:09

TEH EMPRAH