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?
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.
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