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.
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?
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!
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
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!
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With