15

I'm writing a python/flask application and would like to add the functionality of reloading the server.

I'm currently running the server with the following option

app.run(debug=True)

which results in the following, each time a code change happens

* Running on http://127.0.0.1:5000/
* Restarting with reloader

In a production environment however, I would rather not have debug=True set, but be able to only reload the application server whenever I need to.

I'm trying to get two things working:

  1. if reload_needed: reload_server(), and
  2. if a user clicks on a "Reload Server" button in the admin panel, the reload_server() function should be called.

However, despite the fact that the server get's reloaded after code changes, I couldn't find a function that let's me do exactly that.

If possible I would like to use the flask/werkzeug internal capabilities. I am aware that I could achieve something like that by adding things like gunicorn/nginx/apache, etc.

2
  • 2
    Looks like the relevant capabilities of werkzeug, e.g github.com/mitsuhiko/werkzeug/blob/… , are deeply hard-coded to watch the filesystem for changes (directly or via os.stat) to trigger a reload. I think you'll need to modify _reloader.py and offer the patch to werkzeug's authors in order to enable reloading via non-filesystem triggers. Commented Dec 31, 2014 at 16:21
  • This should work: An example on how to reload Flask app in runtime Commented Oct 2, 2019 at 15:44

2 Answers 2

7

I think I've had the same problem.

So there was a python/flask application (XY.py), on clients. I wrote a build step (Teamcity) which deploys this python code to the clients. Let's suppose the XY.py is already running on the clients. After deploying this new/fixed/corrected XY.py I had to restart it for applying the changes on the running code.

The problem what I've had is that after using the fine restarting oneliner os.execl(sys.executable, *([sys.executable]+sys.argv)) my port used by app is still busy/established, so after restarting I can't reach it.

This is how I resolved the problem: I put my app to run on a separate Process and made a queue for it. To see it more cleanly here is some code.

global some_queue = None

@app.route('/restart')
def restart():
   try:
     some_queue.put("something")
     return "Quit"

def start_flaskapp(queue):
   some_queue = queue
   app.run(your_parameters)

Add this to your main:

q = Queue()
p = Process(target=start_flaskapp, args=[q,])
p.start()
while True: #wathing queue, sleep if there is no call, otherwise break
   if q.empty(): 
        time.sleep(1)
   else:
      break
p.terminate() #terminate flaskapp and then restart the app on subprocess
args = [sys.executable] + [sys.argv[0]]
subprocess.call(args)

Hope it was clean and short enough and it helped to you!

Sign up to request clarification or add additional context in comments.

Comments

4

How following in your Python code in order to kill the server:

@app.route('/quit')
def _quit():
    os._exit(0)

When process is killed it will repeat itself in the while loop.

app_run.sh:

#!/bin/bash

while true
do
    hypercorn app_async:app -b 0.0.0.0:5000 
    sleep 1
done

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.