0

I'm trying to code a Flask application which reads the prefs file from disc and also allows down- and upload of that file.

But after uploading, the reload of the file inside the application makes the problem.

Loading at program start works fine as I am doing the following:

prefsfile=os.path.join(app.config['UPLOAD_FOLDER'], 'foo.yaml')

def read_prefs():
    with open(prefsfile, 'r') as file:
        p=yaml.safe_load(file)
    return p

prefs=read_prefs()

Then I have some app.routes who access the prefs object like this, which works fine.

@app.route('/foo')
def foo():
    items=prefs['foo']['items']
    messages=prefs['messages']
    return render_template(
        'foo.html',
        items = items,
        messages = messages
    )

Then I alter the object from inside an app.route and save it also to disc.

def save_prefs():
    with open(prefsfile, 'w') as file:
        yaml.dump(prefs, file)

@app.route('/foo/del_item', methods = ['POST'])
def foo_del_item():
    prefs['foo']['items'].pop(request.form['item_id'])
    save_prefs()
    return redirect(url_for('foo'))

BUT, when I upload the file from a form, then I do not know how to reload the prefs=read_prefs() outside an app.route to make it accessible for all other routes.

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

I tried:

@app.route('/reload_foo')
def reload_foo():
    prefs = read_prefs()

    return redirect(url_for('foo'))

But this works only inside the app.route not for all of them.

The goal is to reload the prefs=read_prefs() outside an app.route to make it accessible for all other app.routes.

davidism
  • 121,510
  • 29
  • 395
  • 339
Cellcore
  • 824
  • 6
  • 8

1 Answers1

0

Global variables, even used with the syntax shown below, will not work as you expect in Flask, as multiple requests might try to modify them simultaneously. See Are global variables thread safe in flask? How do I share data between requests? for correct ways to handle global data in web applications.


prefs is a global variable. If you want to change it inside a function, you need to used the global keyword:

@app.route('/reload_foo')
def reload_foo():
    global prefs
    prefs = read_prefs()
    return redirect(url_for('foo'))

See "What are the rules for local and global variables in Python?" in the documentation.

davidism
  • 121,510
  • 29
  • 395
  • 339
Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103