What Is the G Object in This Flask Code

What is the g object in this Flask code?

g is an object provided by Flask. It is a global namespace for holding any data you want during a single app context. For example, a before_request handler could set g.user, which will be accessible to the route and other functions.

from flask import g

@app.before_request
def load_user():
user = User.query.get(request.session.get("user_id"))
g.user = user

@app.route("/admin")
def admin():
if g.user is None or not g.user.is_admin:
return redirect(url_for("index"))

An app context lasts for one request / response cycle, g is not appropriate for storing data across requests. Use a database, redis, the session, or another external data source for persisting data.


Note that the dev server and any web server will output timing information in the logs already. If you really want to profile your code, you can use the Werkzeug application profiler.

When should Flask.g be used?

Advanced Flask Patterns, as linked by Markus, explains some of the changes to g in 0.10:

  • g now lives in the application context.
  • Every request pushes a new application context, wiping the old one, so g can still be used to set flags per-request without change to code.
  • The application context is popped after teardown_request is called. (Armin's presentation explains this is because things like creating DB connections are tasks which setup the environment for the request, and should not be handled inside before_request and after_request)

Flask app, global variable over multiple files

Just use a regular Python module-level variable.

# app.py

g = "Example"

@app.route("/example")
def example_endpoint():
return g
# main.py

import app

app.g = "Hello"

Quoting the same page you linked:

The application context is created and destroyed as necessary. When a Flask application begins handling a request, it pushes an application context and a request context. When the request ends it pops the request context then the application context. Typically, an application context will have the same lifetime as a request.

So your setting flask.g outside of a request context (in your main.py) doesn't carry your value to anywhere.

Flask: 'session' vs. 'g'?

No, g is not an object to hang session data on. g data is not persisted between requests.

session gives you a place to store data per specific browser. As a user of your Flask app, using a specific browser, returns for more requests, the session data is carried over across those requests.

g on the other hand is data shared between different parts of your code base within one request cycle. g can be set up during before_request hooks, is still available during the teardown_request phase and once the request is done and sent out to the client, g is cleared.

Flask G variable Simple example

Flask g is available in application context and lasts for the lifetime of the request.

What is application context?

As cited on Application Context Page, flask app is in many states while being executed.

One of the design ideas behind Flask is that there are two different “states” in which code is executed. The application setup state in which the application implicitly is on the module level. It starts when the Flask object is instantiated, and it implicitly ends when the first request comes in. While the application is in this state a few assumptions are true:

  • the programmer can modify the application object safely.
  • no request handling happened so far
  • you have to have a reference to the application object in order to modify it, there is no magic proxy that can give you a reference to the application object you’re currently creating or modifying.

In contrast, during request handling, a couple of other rules exist:

  • while a request is active, the context local objects (flask.request and others) point to the current request.
  • any code can get hold of these objects at any time.

There is a third state which is sitting in between a little bit. Sometimes you are dealing with an application in a way that is similar to how you interact with applications during request handling; just that there is no request active. Consider, for instance, that you’re sitting in an interactive Python shell and interacting with the application, or a command line application.

So, basically while you run the app, it exits in many states.

Example : One is serving your requests, one is watching the files for reloading.

If you ever use Celery, then you would have to run it in separate application context. That is when role of g comes into play.
One very common use of celery is to send mails asynchronously.
Imagine you catch a request and after processing it you need to send a mail.
You can store the user information in g to be passed to celery.

Why can't I use flask.g after a request comes?

The wording there is a little awkward. The g object is available during a request as well. A request context is nested inside an application context.

You should store a database connection in the g object because it'll be available *even when there is no request, such as in the flask shell command, and any custom command-line commands. You'll need this when initialising your database, for example.

Next, there are advanced use-cases where you may want to create an 'internal' request, calling another route on your Flask app as if it came from outside. This nested request would re-use the existing app context.

There is never a request context without an application context.

How to persist elements in the Flask g context

Answer your question:

  • Q: How can I make elements survive inside the g proxy object to be used during the entire life of a Flask Application?
  • A: No, you can't. because g persists data only within a context, and it is not an appropriate place to store data between requests (see storing-data#Note for more details.)

Instead of using g, you may use app/current_app to keep some value in .config.
here's the code:

from flask import Flask, g, current_app

def create_app():
app = Flask(__name__)
with app.app_context():
#in context, you can use current_app to fetch or assign app.config['key']
current_app.bb = 'bbb!' # not normally used
current_app.config['aaa'] = 'aaa!' # usually we use current_app.config['name'] = 'value'
print("1", app.bb) # for this example, using app or current_app has no different.
print("1", current_app.config['aaa'])

with app.app_context():
#here to use current_app to get what you want.
print("2", current_app.bb)
print("2", current_app.config['aaa'])

>>>create_app()
1 bbb!
1 aaa!
2 bbb!
2 aaa!

Some Notes: (storing-data (same as above link))

  • current_app is for solving circular import problem.
  • For storing data across requests, using session or database.

When in need to inject elements from the Flask config into the routes defined in some Flask blueprints:

from flask import Blueprint, current_app

...

my_routes = Blueprint("my_routes", __name__)

...

@my_routes.route("/foo_path", methods=["POST"])
def foo_route():
...
my_aaa = current_app.config["aaa"]

If you need to release some resources before shutting down the Flask Application (e.g. release unix sockets, TCP sockets and so on), then you can use a combination of the Flask Config/context and atexit (https://docs.python.org/3/library/atexit.html) like this:

import atexit

def _close_resources(app):
with app.app_context():
app.logger.warning("Closing resources")
current_app.config["aaa_resource"].close()

...

def create_app():

app = Flask(__name__)

def app_close_resources():
return _close_resources(app)

atexit.register(app_close_resources)
...

Unable to use flask.g to access variables in other functions

If you need to track authentication information, I'd suggest one of the Flask plugins like Flask-Login or Flask-Principal.

For example, we use Flask-Principal. It raises the identity-loaded signal when somebody authenticates (or it detects an authentication cookie). We then map their logged-in identity with a user in our database. Something like this:

# not actual code
@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
user = Person.query.filter(Person.username==identity.person.username).one()
g.user = user

and then we can use g.user in any controller or template. (We're actually ripping a lot of this out, it was a easy, lazy hack that's caused more trouble than it's worth.)

If you don't want to use a module, there's a built-in signal you can hook into at the start of every request:

http://flask.pocoo.org/docs/tutorial/dbcon/

# This runs before every request
@app.before_request
def before_request():
g.user = your_magic_user_function()

and g.user would then be magically available everywhere.

I hope that helps!

How to use g.user global in flask

g is a thread local and is per-request (See A Note On Proxies). The session is also a thread local, but in the default context is persisted to a MAC-signed cookie and sent to the client.

The problem that you are running into is that session is rebuilt on each request (since it is sent to the client and the client sends it back to us), while data set on g is only available for the lifetime of this request.

The simplest thing to do (note simple != secure - if you need secure take a look at Flask-Login) is to simply add the user's ID to the session and load the user on each request:

@app.before_request
def load_user():
if session["user_id"]:
user = User.query.filter_by(username=session["user_id"]).first()
else:
user = {"name": "Guest"} # Make it better, use an anonymous User instead

g.user = user


Related Topics



Leave a reply



Submit