0

I'm playing with Flask a little, for my application I would require a global storage which is updated by a Thread running in the background on the server. I found this question about global context and the answer from Johan Gov seems to work if I init the server using /create explicitly:

from flask import Flask
from flask.json import jsonify
app = Flask(__name__)

cache = {}

@app.route("/create")
def create():
    cache['foo'] = 0
    return jsonify(cache['foo'])

@app.route("/increment")
def increment():
    cache['foo'] = cache['foo'] + 1
    return jsonify(cache['foo'])

@app.route("/read")
def read():
    return jsonify(cache['foo'])

if __name__ == '__main__':
    app.run()

If I try to call the init automaticaly however, it fails as apparently no cache["foo"] is known.

from flask import Flask
from flask.json import jsonify
app = Flask(__name__)

cache = {}

def create():        #create does not have a route anymore
    cache['foo'] = 0

@app.route("/increment")
def increment():
    cache['foo'] = cache['foo'] + 1
    return jsonify(cache['foo'])

@app.route("/read")
def read():
    return jsonify(cache['foo'])

if __name__ == '__main__':
    create()    #initialize by default
    app.run()

Why is this happening? How can I initialize global state before starting the Application?

davidism
  • 121,510
  • 29
  • 395
  • 339
Cookie
  • 678
  • 1
  • 11
  • 22

2 Answers2

1

You can use the Cache as your app property, i always use this when i want to avoid awkward global definitions, just define the cache like this:

# here u create a "cache" attribute for the app.
app.cache = {}
app.cache['foo'] = 0

# then after that when calling in a route:
# notice that we don't need the global keyword since we are using the app.
@app.route("/increment")
def increment():
    app.cache = app.cache + 1
    return jsonify(app.cache)

I even used relatively big objects like deep learning models using this method and had not problems at all.

KiLJ4EdeN
  • 206
  • 2
  • 6
  • thanks for your reply. The solution is right (works), thanks a lot. But there's a typo in it. All occurrences of app['cache'] should be app.cache imo. Maybe you can correct that and I can accept your answer – Cookie Jan 23 '21 at 14:04
  • Actually what i meant was app.config['cache'], but still, the dot method (app.cache) seems a lot cleaner so i have changed it. – KiLJ4EdeN Jan 24 '21 at 03:54
0

tbh, the above code work for me without any change and I'm able to read and increment counter.

Try below code with global variable

from flask import Flask
from flask.json import jsonify

app = Flask(__name__)

cache = {}


def create():  # create does not have a route anymore
    global cache
    cache['foo'] = 0


@app.route("/increment")
def increment():
    global cache
    cache['foo'] = cache['foo'] + 1
    return jsonify(cache['foo'])


@app.route("/read")
def read():
    return jsonify(cache['foo'])


if __name__ == '__main__':
    create()  # initialize by default
    app.run()
gsb22
  • 2,112
  • 2
  • 10
  • 25
  • thanks for your reply. unfortunately it won't work, no matter if with or without "global" keyword. However the above solution from KiLJ4deN works for me – Cookie Jan 23 '21 at 14:07