-
-
Save nguyenkims/ff0c0c52b6a15ddd16832c562f2cae1d to your computer and use it in GitHub Desktop.
""" | |
This is an example on how to reload Flask app in runtime | |
It can be useful for the use case where you want to enable/disable blueprints/routes dynamically. | |
To run the app: | |
> pip install flask & python app.py | |
Then test it via curl | |
> curl localhost:5000/ | |
> curl localhost:5000/reload | |
> curl localhost:5000/ # should see a different start time as the flask app is replaced | |
""" | |
from datetime import datetime | |
from flask import Flask | |
from werkzeug.serving import run_simple | |
# set to True to inform that the app needs to be re-created | |
to_reload = False | |
def get_app(): | |
print("create app now") | |
app = Flask(__name__) | |
# to make sure of the new app instance | |
now = datetime.now() | |
@app.route("/") | |
def index(): | |
return f"hello, the app started at %s" % now | |
@app.route('/reload') | |
def reload(): | |
global to_reload | |
to_reload = True | |
return "reloaded" | |
return app | |
class AppReloader(object): | |
def __init__(self, create_app): | |
self.create_app = create_app | |
self.app = create_app() | |
def get_application(self): | |
global to_reload | |
if to_reload: | |
self.app = self.create_app() | |
to_reload = False | |
return self.app | |
def __call__(self, environ, start_response): | |
app = self.get_application() | |
return app(environ, start_response) | |
# This application object can be used in any WSGI server | |
# for example in gunicorn, you can run "gunicorn app" | |
application = AppReloader(get_app) | |
if __name__ == '__main__': | |
run_simple('localhost', 5000, application, | |
use_reloader=True, use_debugger=True, use_evalex=True) |
Im keen to find a way to reload config and the app. Im looking to take DB settings from a form and load them into the application to use.
@darryllane
Same here. I got the values loaded from the database, my problem is getting the new settings to take when they are changed without manually reloading the application.
EDIT: What I ended up doing was creating a file in the root folder, opening the file and re-writing what was already in there to it. I'm using Gunicorn and added the --reload-extra-file command to monitor that file for changes. After I make my settings changes in the database, I change the file which causes a reload of the app. Probably not the most elegant or proper solution, but it works.
Im keen to find a way to reload config and the app. Im looking to take DB settings from a form and load them into the application to use.
@darryllane
Same here. I got the values loaded from the database, my problem is getting the new settings to take when they are changed without manually reloading the application.EDIT: What I ended up doing was creating a file in the root folder, opening the file and re-writing what was already in there to it. I'm using Gunicorn and added the --reload-extra-file command to monitor that file for changes. After I make my settings changes in the database, I change the file which causes a reload of the app. Probably not the most elegant or proper solution, but it works.
I did a similar thing with gunicorn.
When I run gunicorn I run it like this gunicorn -b 0.0.0.0:8000 -p app.pid run:app
so I get the PID number in a file. To restart it I'm sending HUP signal that restarts the server by checking all the workers finished their tasks.
`
import os
from app import create_app
app = create_app()
class CommandRunner():
@staticmethod
def restart_server():
path = os.path.join(app.root_path,"..","app.pid")
if os.path.exists(path):
with open(path,"r+") as file:
pid = file.read()
cmd = "kill -s HUP "+pid
os.system(cmd)
`
Which is also not a proper one. Please keep this thread updated if you guys find any other elegant solution.
I was looking some ways to do an actual reload, and as of this writing, i thought, why not run the entire flask app from a subprocess perspective, then kill it and call the subprocess again to start the server again. The key here is to save the PID of the process into a file, and use it to get the PID and execute os.kill from flask's route
lets say main.py
def start():
process = Popen(['python','run.py'],shell=True)
with open('PID.file','w+') as pidfile:
pidfile.write(process.pid)
& app.py
@app.route('reload')
def reload():
with open('PID;file','r') as pidfile:
pid = pidfile.read()
os.kill(pid,, signal.SIGKILL)
main.start()
I ran into a similar issue where I needed to reload a Flask site theme configuration.
I simply created a method that imported the current Flask application and then manually updated certain configurations.
I later executed the reload
method within a Flask controller method.
In my use case, I needed to update the template and assets path but you could add whatever needs to be updated.
def reload():
from flask import current_application
current_application.template_folder = "new/path/to/templates"
current_application.static_folder = "new/path/to/static/folder"
# Add whatever configuration that needs to be updated
Im keen to find a way to reload config and the app. Im looking to take DB settings from a form and load them into the application to use.