3

I try to create application based on web technology. The flask block main application. How to make it run in other thread or process. so, main process not get block. its better run in thread. cause, as user try to close main application, http server should stop too.

from flask import Flask
import tkinter
from multiprocessing import Process
import threading

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

server = None

def toggle():
    match run_btn.cget("text"):
        case "Start":
            server = Process(app.run())
            server.start()
        
        case "Stop":
            server.terminate()

if __name__ == "__main__":
   root = tkinter.Tk()
   run_btn = tkinter.Button(root, text = "Start", command = toggle)
   run_btn.pack()
   root.mainloop()
ti7
  • 16,375
  • 6
  • 40
  • 68
jennie
  • 45
  • 5
  • there are many strategies ([greenlets](https://stackoverflow.com/questions/35837786/#comment59345522_35839360), spawning a great number of unique instances of the server or workers within it, squeezing a lot of performance so it's just really fast, ..), but practically using an async webserver (Tornado, FastAPI, ..) and packing the work into some queue for some pool of processors to handle and `await` a response is often the right strategy - WSGI-based frameworks suffer greatly when more processing is wanted than serving a templated page, despite widespread adoption – ti7 Feb 07 '22 at 19:41
  • Wouldn't this line `server = Process(app.run())` simply run the flask app in the parent process? – Ankur Feb 07 '22 at 19:59
  • @Ankur flask dont have method to stop. – jennie Feb 07 '22 at 20:02
  • 2
    In the above example, `app.run()` is evaluated first and blocks forever (in the main thread) `Process(...)` is never evaluated. You probably meant `Process(target=app.run)` Though, I don't think that's a sane way to run Flask. – sytech Feb 07 '22 at 20:23
  • specifically with the code above, if you're getting `AttributeError: 'NoneType' object has no attribute 'terminate'`, this happens because you use the name `server` within the scope of `toggle()` without noting that it should refer to the outer name (set `None` in the body above), making it a local that's lost when `toggle()` returns.. while you could (though this is bad practice, it will work immediately for testing), declare `global server` before you have `server = Process(app.run())` to use the outer name – ti7 Feb 07 '22 at 20:44

0 Answers0