flask:发生异常后停止服务器



一旦发生未处理的异常,我想立即停止烧瓶服务器。这里有一个例子:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
1/0 # argh, exception
return 'Hello World!'

if __name__ == '__main__':
app.run(port=12345)

如果您运行此程序并转到localhost:12345,浏览器告诉您"内部服务器错误",并且python控制台记录DivisionByZero异常。

但服务器应用程序不会崩溃。Flask将您的路由封装到自己的错误处理中,并且只打印异常。

我希望在路由产生异常时立即停止服务器。但我没有在API中发现这种行为。您可以指定错误处理程序,但这只是在路由失败后向客户端提供自定义错误消息。

停止烧瓶需要进入Werkzeug内部。看见http://flask.pocoo.org/snippets/67/

从单个用户应用程序中提取:

from flask import request
@app.route('/quit')
def shutdown():
...
shutdown_hook = request.environ.get('werkzeug.server.shutdown')
if shutdown_hook is not None:
shutdown_hook()
return Response("Bye", mimetype='text/plain')

shutdown_hook位是异常处理程序中所需要的。

from multiprocessing import Process
server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()

或者如果线程运行Flask Web服务器在后台围绕其他python代码:

import threading
import ctypes
webserverurl  = 127.0.0.1
webserverport = 8080
class thread_with_exception(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
self.interval = 1
self.daemon = True

def __del__(self):
print(f"Thread terminated");

def run(self):
# target function of the thread class
try:
while True:
print(f"{self.name} Waiting for Web")
app.run(host=webserverurl, port=webserverport)
finally:
print('ended')

def get_id(self):
# returns id of the respective thread
if hasattr(self, '_thread_id'):
return self._thread_id
for id, thread in threading._active.items():
if thread is self:
return id

def raise_exception(self):
thread_id = self.get_id()
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), ctypes.py_object(SystemExit))
print(f"{self.name} terminated")
if res > 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), 0)
print('Exception raise failure')
t1 = thread_with_exception('Web Server 1')
t1.start()
time.sleep(10)
t1.raise_exception()
# del t1

Andrew Abrahamowicz的信用:https://code.activestate.com/recipes/496960-thread2-killable-threads

Linux需要ctypes.c_long(,其他仅限Windows:https://stackoverflow.com/a/61638782/3426192

  • 在此处执行此操作的其他方法:https://w3guides.com/tutorial/how-to-close-a-flask-web-server-with-python

最新更新