Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask session variable not persisting between requests

Using the app below and Flask 0.11.1, I navigated to the routes associated with the following function calls, with the given results:

  • create(): '1,2,3' # OK
  • remove(1) : '2,3' # OK
  • remove(2) : '1,3' # expected '3'
  • maintain(): '1,2,3' # expected '1,3' or '3'

 

from flask import Flask, session

app = Flask(__name__)

@app.route('/')
def create():
    session['list'] = ['1','2','3']
    return ",".join(session['list'])

@app.route('/m')
def maintain():
    return ",".join(session['list'])

@app.route('/r/<int:id>')
def remove(id):
    session['list'].remove(str(id))
    return ",".join(session['list'])

if __name__ == '__main__':
    app.secret_key = "123"
    app.run()

This question is similar in theme to this question, this, and this one, but I'm setting the secret key and not regenerating it, and my variable is certainly not larger than the 4096 bytes allowed for cookies. Perhaps I'm missing some more basic understanding about Flask session variables?

like image 656
techmonk Avatar asked Sep 01 '16 01:09

techmonk


3 Answers

From the doc:

Be advised that modifications on mutable structures are not picked up automatically, in that situation you have to explicitly set the [modified attribute] to True yourself.

Try:

session['list'].remove(str(id))
session.modified = True
like image 171
Robᵩ Avatar answered Nov 14 '22 23:11

Robᵩ


Flask uses a CallbackDict to track modifications to sessions.

It will only register modifications when you set or delete a key. Here, you modify the values in place, which it will not detect. Try this:

@app.route('/r/<int:id>')
def remove(id):
    val = session['list']
    val.remove(str(id))
    session['list'] = val
    return ",".join(session['list'])

…and same with other changes.

Alternatively, you can flag the modification yourself instead of triggering the detection:

@app.route('/r/<int:id>')
def remove(id):
    session['list'].remove(str(id))
    session.modified = True
    return ",".join(session['list'])
like image 44
spectras Avatar answered Nov 15 '22 00:11

spectras


I was having this same problem and I found out that my changes in the session were not persisting because my data was too big.

From here:

"By default, there isn't much difference between cookies and client-based sessions in Flask. As a result, the client-based sessions suffer from the same drawbacks the cookies have like:

  • Can't store sensitive data like passwords.
  • Additional payload on every request.
  • Can't store data more than 4KB.
  • Limit on the number of cookie per website and so on.

If your data is larger than 4KB, a server-side Session is needed. Have a look at Flask-Session.

like image 1
Matheus Torquato Avatar answered Nov 14 '22 22:11

Matheus Torquato