0

I'm new to both flask and python. I've got an application I'm working on to hold weather data. I'm allowing for both get and post commands to come into my flask application. unfortunately, the automated calls for my API are not always coming back with the proper results. I'm currently storing my data in a global variable when a post command is called, the new data is appended to my existing data. Unfortunately sometimes when the get is called, it is not receiving the most up to date version of my global data variable. I believe that the issue is that the change is not being passed up from the post function to the global variable before the get is called because I can run the get and the proper result comes back.

weatherData = [filed with data read from csv on initialization]

class FullHistory(Resource):
    def get(self):
        ret = [];
        for row in weatherData:
            val = row['DATE']
            ret.append({"DATE":str(val)})
        return ret

    def post(self):
        global weatherData
        newWeatherData = weatherData
        args = parser.parse_args()
        newVal = int(args['DATE'])
        newWeatherData.append({'DATE':int(args['DATE']),'TMAX':float(args['TMAX']),'TMIN':float(args['TMIN'])})
        weatherData = newWeatherData
        #time.sleep(5)
        return {"DATE":str(newVal)},201

class SelectHistory(Resource):
    def get(self, date_id):
        val = int(date_id)
        bVal = False
        #time.sleep(5)
        global weatherData
        for row in weatherData:
            if(row['DATE'] == val):
                wd = row
                bVal = True
                break
        if bVal:
            return {"DATE":str(wd['DATE']),"TMAX":float(wd['TMAX']),"TMIN":float(wd['TMIN'])}
        else:
            return "HTTP Error code 404",404
    def delete(self, date_id):
        val = int(date_id)
        wdIter = None
        for row in weatherData:
            if(row['DATE'] == val):
                wdIter = row
                break
        if wdIter != None:
            weatherData.remove(wdIter)
            return {"DATE":str(val)},204
        else:
            return "HTTP Error code 404",404

Is there any way I can assure that my global variable is up to date or make my API wait to return until I'm sure that the update has been passed along? This was supposed to be a simple application. I would really rather not have to learn how to use threads in python just yet. I've made sure that my calls get request is not starting until after the post has given a response. I know that one workaround was to use sleep to delay my responses, I would rather understand why my update isn't occurring immediately in the first place.

  • 1
    Every time you use a global variable in Python a kitten dies. In Flask they don't even work. – Klaus D. Mar 14 '17 at 05:04
  • Possible duplicate of [Preserving global state in a flask application](http://stackoverflow.com/questions/19277280/preserving-global-state-in-a-flask-application) – Ilja Everilä Mar 14 '17 at 05:04

1 Answers1

0

I believe your problem is the application context. As stated here:

The application context is created and destroyed as necessary. It never moves between threads and it will not be shared between requests. As such it is the perfect place to store database connection information and other things. The internal stack object is called flask._app_ctx_stack. Extensions are free to store additional information on the topmost level, assuming they pick a sufficiently unique name and should put their information there, instead of on the flask.g object which is reserved for user code.

Though it says you can store data at the "topmost level," it's not reliable, and if you extrapolate your project to use worker processes with uWSGI, for instance, you'll need persistence to share data between threads regardless. You should be using a database, redis, or at very least updating your .csv file each time you mutate your data.

Allie Fitter
  • 1,689
  • 14
  • 18