Flask route doesn’t update backend status

I’m currently working on a Flask web application that makes multiple API calls. I want to improve transparency for users by sending dynamic status updates to the frontend to indicate which API call the application is currently at. I’ve tried to achieve this using a global variable and a dedicated status route, but it’s not working as expected.

My Question:

The status route doesn’t seem to update as expected. Can anyone help me solve this problem or suggest a better method to send the status dynamically to the frontend?

Problem Statement:

I have a global variable current_status to store the current status.
I update this variable in my API call functions to reflect the respective status.

from flask import Flask, jsonify

app = Flask(__name__)

# Global variable to store the current status
current_status = "Initial Status"

# Route to get the current status
@app.route('/status', methods=['GET'])
def get_status():
    return jsonify({'status': current_status})

# Example method to update the status
@app.route('/update_status/<string:new_status>', methods=['PUT'])
def update_status(new_status):
    global current_status
    current_status = new_status
    return jsonify({'message': 'Status has been updated', 'new_status': current_status})

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

How would I work with this set up to update the routes status?

  • Have you tried doing it with sessions? flask.palletsprojects.com/en/3.0.x/api/#sessions

    – 

  • I would recommend storing it in a file rather than a global variable, using global is not proper for web applications, I mean when you restart the flask, the status is lost; if your flask is working in prefork mode, the status things is not global actually

    – 

If you want to store global state for you flask application, you’re going to need to store that data somewhere external to your application. As @moon548834 suggested, one option is store this in a local file. This works fine if your application runs on a single server; you’ll need to implement appropriate locking in order to access the file from multiple threads/processes without causing a problem.

A possible solution use the built-in fcntl module might look like this:

import fcntl
from flask import Flask, jsonify

app = Flask(__name__)

class StateFile:
    def __init__(self, path, lockfile=None):
        self.path = path
        self.lockfile = lockfile if lockfile else f'{self.path}.lock'

    def __enter__(self):
        self._fd = open(self.lockfile, 'w')
        fcntl.lockf(self._fd, fcntl.LOCK_EX)
        return self

    def __exit__(self, *_):
        fcntl.lockf(self._fd, fcntl.LOCK_UN)
        self._fd.close()

    def get(self):
        with open(self.path, 'r') as fd:
            return fd.read()

    def put(self, data):
        with open(self.path, 'w') as fd:
            fd.write(data)
            fd.truncate()

# Global variable to store the current status
current_status = StateFile('status.txt')
with current_status:
    current_status.put('initial status')

# Route to get the current status
@app.route('/status', methods=['GET'])
def get_status():
    with current_status:
        return jsonify({'status': current_status.get()})

# Example method to update the status
@app.route('/update_status/<string:new_status>', methods=['PUT'])
def update_status(new_status):
    with current_status:
        current_status.put(new_status)
        return jsonify({'message': 'Status has been updated', 'new_status': current_status.get()})

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

Depending on your needs (e.g., if you application needs to run across multiple servers), you could use a database like Postgresql or an in-memory data store like Redis for storing your status information.

Leave a Comment