Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserving global state in a flask application [duplicate]

I am trying to save a cache dictionary in my flask application.

As far as I understand it, the Application Context, in particular the flask.g object should be used for this.

Setup:

import flask as f  app = f.Flask(__name__) 

Now if I do:

with app.app_context():     f.g.foo = "bar"     print f.g.foo 

It prints bar.

Continuing with the following:

with app.app_context():     print f.g.foo  AttributeError: '_AppCtxGlobals' object has no attribute 'foo' 

I don’t understand it and the docs are not helping at all. If I read them correctly the state should have been preserved.

Another idea I had was to simply use module-wide variables:

cache = {}  def some_function():     cache['foo'] = "bar" 

But it seems like these get reset with every request.

How to do this correctly?

Edit: Flask 10.1

like image 736
Profpatsch Avatar asked Oct 09 '13 16:10

Profpatsch


People also ask

Are global variables thread safe in Flask?

Global variables are still not thread safe because there's still no protection against most race conditions. You can still have a scenario where one worker gets a value, yields, another modifies it, yields, then the first worker also modifies it.

Why does running the Flask dev server run itself twice?

The reason for this is that due to how the reload mechanism works there are some bizarre side-effects (like executing certain code twice...)

How does Flask handle multiple concurrent requests?

The server component that comes with Flask is really only meant for when you are developing your application; even though it can be configured to handle concurrent requests with app. run(threaded=True) (as of Flask 1.0 this is the default).


1 Answers

Based on your question, I think you're confused about the definition of "global".

In a stock Flask setup, you have a Flask server with multiple threads and potentially multiple processes handling requests. Suppose you had a stock global variable like "itemlist = []", and you wanted to keep adding to it in every request - say, every time someone made a POST request to an endpoint. This is totally possible in theory and practice. It's also a really bad idea.

The problem is that you can't easily control which threads and processes "win" - the list could up in a really wonky order, or get corrupted entirely. So now you need to talk about locks, mutexs, and other primitives. This is hard and annoying.

You should keep the webserver itself as stateless as possible. Each request should be totally independent and not share any state in the server. Instead, use a database or caching layer which will handle the state for you. This seems more complicated but is actually simpler in practice. Check out SQLite for example ; it's pretty simple.

To address the 'flask.g' object, that is a global object on a per request basis.

http://flask.pocoo.org/docs/api/#flask.g

It's "wiped clean" between requests and cannot be used to share state between them.

like image 133
mallyvai Avatar answered Oct 08 '22 00:10

mallyvai