Are Global Variables Thread-Safe in Flask? How to Share Data Between Requests

Are global variables thread-safe in Flask? How do I share data between requests?

You can't use global variables to hold this sort of data. Not only is it not thread safe, it's not process safe, and WSGI servers in production spawn multiple processes. Not only would your counts be wrong if you were using threads to handle requests, they would also vary depending on which process handled the request.

Use a data source outside of Flask to hold global data. A database, memcached, or redis are all appropriate separate storage areas, depending on your needs. If you need to load and access Python data, consider multiprocessing.Manager. You could also use the session for simple data that is per-user.


The development server may run in single thread and process. You won't see the behavior you describe since each request will be handled synchronously. Enable threads or processes and you will see it. app.run(threaded=True) or app.run(processes=10). (In 1.0 the server is threaded by default.)


Some WSGI servers may support gevent or another async worker. 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.


If you need to store some global data during a request, you may use Flask's g object. Another common case is some top-level object that manages database connections. The distinction for this type of "global" is that it's unique to each request, not used between requests, and there's something managing the set up and teardown of the resource.

Unable to share variables between 2 flasks requests in a view function

The linked answer appears to be completely wrong. The g object is for storing global data from one function to another within the same request, and is not at all for sharing data between requests.

For that you need sessions:

from flask import Flask, session

@home.route('/save', methods=['GET'])
def save_ressource():
an_object = {'key': 'value'}
session['an_object'] = an_object
return 'sucees'

@home.route('/read', methods=['GET'])
def read_ressource():
an_object = session.get('an_object')
if an_object:
return 'sucess'
else:
return 'failure'

Preserving global state in a flask application

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.

How to properly store a global variable in flask application

You can add the repo to UPLOAD FOLDER in app.config. Add these lines to your flaskapp (at the beginning):

UPLOAD_FOLDER = 'your_path'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'jfif'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

And inside route that handles the file, add this:

file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))

Alternatively, you can create a txt file (let's name it 'repo.txt') and write the repo in it. Then load it in your flask (either as global variable or in specific routes, the second is recommended) with:

with open('repo.txt', 'r') as f:
myrepo=f.read()

This way you will just have to update the txt file instead of the app itself



Related Topics



Leave a reply



Submit