How does the life cycle and visibility of the Flask object work. g?

Asked

Viewed 126 times

2

In Flask there’s an object called g or Flask.g that according to the documentation is used for data storage. And this object is used when assigning something to it.

For example:

def get_db():
    if 'db' not in g:
        g.db = sqlite3.connect(
            current_app.config['DATABASE'],
            detect_types=sqlite3.PARSE_DECLTYPES
        )
        g.db.row_factory = sqlite3.Row

    return g.db

Up in g.db a database access instance is stored. However, I have some doubts regarding the visibility scope and life cycle of this object g during their use.

Doubts

  1. The object g is visible only in the scope of the request and it is released from memory as soon as the request is completed?
  2. The object g is visible between Blueprints?
  3. The life cycle of g is for the whole context of the application?

1 answer

3


  1. The object g is visible only in the scope of the request and it is released from memory as soon as the request is completed?

Yes.

  1. Object g is visible between Blueprints?

Yes. It exists while in the same request - so if in a view method, you call via Python, as a function, a function that works as a view in another Blueprint, it sees the same "g".

However, of course each request accesses only one Blueprint - where the view that responded to that request is configured. Another request that calls a view function in another Blueprint will "see" another "g" object, different from the first one. And this is so ,even if they are asynchronous requests made at almost the same time, and are processed at the same time on the server: different requests will see different context objects g.

  1. The life cycle of g is for the whole application context?

"g" is accessible anywhere and any function of the application - but, again, each request will "see" a different object when doing "flask. g".

At the beginning of Flask, flask. g was simply a variable of type thread.local - today, with more ways to meet concurrent requests in production than simply one in each thread, application servers have to take care to have all the code related to a request see a copy of "g".

The official documentation is here: http://flask.pocoo.org/docs/1.0/appcontext/#storing-data

What’s odd about "g" is that that’s actually not how normal variables work - but that’s exactly how thread.locale objects work. I created here a small script that demonstrates how the attributes inside an object of type threading.local are unique in each thread:

import threading
import time

def worker(number, pause):
    time.sleep(0.1)
    espaco.teste = number
    print(f"thread {number}: Valor de espaco.teste {espaco.teste}")
    time.sleep(pause)
    print(f"thread {number}: Valor de espaco.teste {espaco.teste}")


def main():
    global espaco
    espaco = threading.local()
    espaco.teste = 0
    t1 = threading.Thread(target=worker, args=(1, 1.0))
    t2 = threading.Thread(target=worker, args=(2, 0.5))
    print(f"thread princial. Espaco.teste: {espaco.teste}")
    t1.start()
    t2.start()
    time.sleep(0.2)
    print(f"thread principal. Espaco.teste: {espaco.teste}")

    t1.join()
    t2.join()

main()

The output of this script looks like this:

(env) [gwidion@village tmp01]$ python3 bla10.py 
thread principal. Espaco.teste: 0
thread 1: Valor de espaco.teste 1
thread 2: Valor de espaco.teste 2
thread principal. Espaco.teste: 0
thread 2: Valor de espaco.teste 2
thread 1: Valor de espaco.teste 1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.