0

I am using:

  • Python 3.6.1
  • Flask 0.12.2

Section on session of Flask documentation says that:

This is a proxy.

and section on proxies elaborates that:

Some of the objects provided by Flask are proxies to other objects. The reason behind this is that these proxies are shared between threads and they have to dispatch to the actual object bound to a thread behind the scenes as necessary.
...
If you need to get access to the underlying object that is proxied, you can use the _get_current_object() method

This all is pretty much straightforward.
But when I try the following:

from flask import (
Flask,
session,
)

app = Flask(__name__)
app.secret_key = 'some random secret key'

@app.route('/')
def index():
    print("session ID is: {}".format(id(session)))
    print("session._get_current_object() ID is: {}".format(id(session._get_current_object())))
    print('________________________________')

    return 'Check the console! ;-)'

each time I make a request to / — the value of id(session._get_current_object()) is different, while id(session) remains the same.

Following Flask documentation, quoted above, it should be the other way around. So why is this happening?


UPDATE
inspired by brunns's suggestion in the comments to his answer, that there is one underlying object per thread

Here is some code, to test assumption that there is one underlying session object (session._get_current_object()) per thread:

import threading

from flask import (
Flask,
session,
)

app = Flask(__name__)
app.secret_key = 'some random secret key'

@app.route('/')
def index():
    print("session ID is: {}".format(id(session)))
    print("session._get_current_object() ID is: {}".format(id(session._get_current_object())))
    print("threading.current_thread().ident is: {}".format(threading.current_thread().ident))
    print('________________________________')
    return 'Check the console! ;-)'

Despite the expectations, threading.current_thread().ident) is never changed, while is id(session._get_current_object() is changing.

1 Answers1

2

session is an object you have imported from the flask module. You only import it once, and it doesn't change, so nor will its id(). It's shared between threads, and it's a proxy to the underlying objects.

Each request may be run on a different thread, and each will have a different underlying object, so they may have different id()s.

brunns
  • 2,689
  • 1
  • 13
  • 24
  • Thanks for the answer. I think, I now understand why `id(session)` never changes. Though I am still confused about `session._get_current_object()`. Could you please elaborate on the following: what `session` is proxying to, if the underlying object is changed after each request ? My (_incorrect_) understanding is (_?was_) is that there is only one underlying object for all threads (which remains unchanged, for the session's lifetime), and `session` is a proxy to that object. What is, then, returned by `session._get_current_object()`? Is it also a proxy object (if so, what is it proxying to)? –  Apr 22 '19 at 03:38
  • 1
    My understanding was that there was one underlying object ber thread (not per request) so you'll see many different `id`s, but there will be repeats. Beyond that, sorry, but you're getting beyond my knowledge! – brunns Apr 22 '19 at 05:53
  • Thanks for sharing your knowledge, it helped me to advance my own understanding of the matter. –  Apr 23 '19 at 04:35
  • Though, I have tested if `session._get_current_object()` is changing together with thread id — and it is not (see example I have added to the question). –  Apr 23 '19 at 06:12
  • You, might be interested by [an answer](https://stackoverflow.com/a/55809062/8554766) to my another question, which explains that object proxied by `session` is, in fact, belongs to [`RequestContext`](http://flask.pocoo.org/docs/1.0/api/#flask.ctx.RequestContext). –  Apr 24 '19 at 09:46
  • 2
    The proxied session objects are created for each and every request, so their ids are expected to be different. – Martijn Pieters Apr 24 '19 at 12:03