During investigation of another conundrum that I had with Flask sessions, I have tried to better my understanding of how Flask sessions work, in general.
According to Flask documentation on sessions session
object itself is a proxy.
My understanding (that is, in all probability, wrong in some way, and this is what this question is about =) of what it means is:
the proxy
session
object is accessed from the app and is used to modify read data as needednormally, proxy-
session
will transfer it's changes to proxied-session
right away (except for the change of mutables in proxy-session
)in case if proxied-
session
is busy (in case of a multi-thread app), proxy-session
will wait until proxied-session
available, and then transfer it's changes to proxied-session
templates receive the 'original' session (i.e. proxied-
session
), so there is no ability/need to accesssession._get_current_object()
from the templatesas dictionaries (which
session
is) are mutable, I'd assume it's id should remain unchanged for the length of session (though content could be modified)the actual
session
(proxied object, that is available viasession._get_current_object()
) should never change itsID
Now, when I have tried to check my assumptions - the behaviour I've encountered confused me a bit.
Consider the following code:
my_app.py
from flask import (
Flask,
render_template,
session,
)
app = Flask(__name__)
app.secret_key = 'some random secret key'
@app.route('/create/')
def create():
session['example'] = ['one', 'two']
print_ids()
return str(session['example'])
@app.route('/modify/')
def modify():
session['example'].append('three')
print_ids()
return render_template('my_template.html', id=id)
@app.route('/display/')
def display():
print_ids()
return str(session['example'])
def print_ids():
import inspect
calling_function = inspect.stack()[1][3]
print('')
print(calling_function + ": session ID is: {}".format(id(session)))
print(calling_function + ": session['example'] ID is {}".format(id(session['example'])))
print('________________________________')
print(calling_function + ": session._get_current_object() ID is: {}".format(id(session._get_current_object())))
print(calling_function + ": session._get_current_object()['example'] ID is: {}".format(id(session._get_current_object()['example'])))
my_template.html
<!doctype html>
<html>
<head><title>Display session['example']</title></head>
<body>
<div>
{% if session['example'] %}
{{ session['example'] }}
<br />
session ID is: {{ id(session) }}
<br />
session['example'] ID is: {{ id(session['example']) }}
<br />
{% else %}
session['example'] is not set =(
{% endif %}
</div>
</body>
</html>
The idea is to print id's of proxy-session
, session['example']
(which is a list), proxied-session
(i.e. session._get_current_object()
) and proxied-session['example']
(i.e. session._get_current_object()['example']
) from every function, as well as id(session)
and id(session['example'])
on the rendered template, in order to track down what is used where.
Here are the results:
.../create/
# id(session) 4338311808
# id(session._get_current_object()) 4343709776
# id(session['example']) 4343654376
# id(session._get_current_object()['example']) 4343654376
.../modify/
# id(session) 4338311808
# id(session._get_current_object()) 4344315984
# id(session['example']) 4343652720
# id(session._get_current_object()['example']) 4343652720
rendered my_template.html
# id(session) 4344315984
# id(session['example']) 4343652720
.../display/
# id(session) 4338311808
# id(session._get_current_object()) 4344471632
# id(session['example']) 4341829576
# id(session._get_current_object()['example']) 4341829576
# one more time
.../display/
# id(session) 4338311808
# id(session._get_current_object()) 4344471632
# id(session['example']) 4344378072
# id(session._get_current_object()['example']) 4344378072
Things I'm striving to understand are:
- What are my misunderstandings/wrong assumptions, concerning Flask sessions concept, in general?
- Why ids of
session['example']
andsession._get_current_object()['example']
are changed on every hit of display (and every other method, but display in particular, since it does not modify anything, I would expect all ids to remain unchanged)? - Why id of
session._get_current_object()
changes and id ofsession
is not? Since ids of
session['example']
andsession._get_current_object()['example']
are identical in context of any function, I would assume that if one object is changed - then both are changed, as they are the same object.With that being said, and taking into account that
session._get_current_object()['example']
is inside proxied (i.e. 'real')session
I'd expect the following:
.../create/ # return ['one', 'two']
.../modify/ # will render page containing ['one', 'two', 'three']
.../display/ # return ['one', 'two', 'three'] as proxy and proxied sessions should have been modified
But as I have previously discovered - it's not happening. So why ids are the same?