I want to implement a command which can stop flask application by using flask-script. I have searched the solution for a while. Because the framework doesn't provide "app.stop()" API, I am curious about how to code this. I am working on Ubuntu 12.10 and Python 2.7.3.
我想通过使用flask-script来实现一个可以停止烧瓶应用的命令。我已经搜索了一段时间的解决方案。因为框架不提供“app.stop()”API,所以我很好奇如何编写代码。我正在研究Ubuntu 12.10和Python 2.7.3。
5 个解决方案
#1
51
If you are just running the server on your desktop, you can expose an endpoint to kill the server (read more at Shutdown The Simple Server):
如果您只是在桌面上运行服务器,则可以公开端点以终止服务器(在关闭简单服务器时阅读更多信息):
from flask import request
def shutdown_server():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
@app.route('/shutdown', methods=['POST'])
def shutdown():
shutdown_server()
return 'Server shutting down...'
Here is another approach that is more contained:
这是另一种更加包含的方法:
from multiprocessing import Process
server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()
Let me know if this helps.
如果这有帮助,请告诉我。
#2
12
I did it slightly different using threads
我使用线程做的略有不同
from werkzeug.serving import make_server
class ServerThread(threading.Thread):
def __init__(self, app):
threading.Thread.__init__(self)
self.srv = make_server('127.0.0.1', 5000, app)
self.ctx = app.app_context()
self.ctx.push()
def run(self):
log.info('starting server')
self.srv.serve_forever()
def shutdown(self):
self.srv.shutdown()
def start_server():
global server
app = flask.Flask('myapp')
...
server = ServerThread(app)
server.start()
log.info('server started')
def stop_server():
global server
server.shutdown()
I use it to do end to end tests for restful api, where I can send requests using the python requests library.
我使用它来为restful api做端到端测试,我可以使用python请求库发送请求。
#3
5
My method can be proceeded via bash terminal/console
我的方法可以通过bash终端/控制台进行
1) run and get the process number
1)运行并获取进程号
$ ps aux | grep yourAppKeywords
2a) kill the process
2a)杀死进程
$ kill processNum
2b) kill the process if above not working
2b)如果上面没有工作就杀了这个过程
$ kill -9 processNum
#4
4
As others have pointed out, you can only use werkzeug.server.shutdown
from a request handler. The only way I've found to shut down the server at another time is to send a request to yourself. For example, the /kill
handler in this snippet will kill the dev server unless another request comes in during the next second:
正如其他人指出的那样,您只能从请求处理程序中使用werkzeug.server.shutdown。我发现在另一个时间关闭服务器的唯一方法是向自己发送请求。例如,此代码段中的/ kill处理程序将终止开发服务器,除非在下一秒内有另一个请求进入:
import requests
from threading import Timer
import time
LAST_REQUEST_MS = 0
@app.before_request
def update_last_request_ms():
global LAST_REQUEST_MS
LAST_REQUEST_MS = time.time() * 1000
@app.route('/seriouslykill', methods=['POST'])
def seriouslykill():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
return "Shutting down..."
@app.route('/kill', methods=['POST'])
def kill():
last_ms = LAST_REQUEST_MS
def shutdown():
if LAST_REQUEST_MS <= last_ms: # subsequent requests abort shutdown
requests.post('http://localhost:5000/seriouslykill')
else:
pass
Timer(1.0, shutdown).start() # wait 1 second
return "Shutting down..."
#5
2
This is an old question, but googling didn't give me any insight in how to accomplish this.
这是一个老问题,但谷歌搜索没有给我任何洞察力如何实现这一目标。
Because I didn't read the code here properly! (Doh!) What it does is to raise a RuntimeError
when there is no werkzeug.server.shutdown
in the request.environ
...
因为我没有在这里正确阅读代码! (Doh!)它的作用是在request.environ中没有werkzeug.server.shutdown时引发RuntimeError ...
So what we can do when there is no request
is to raise a RuntimeError
所以当没有请求时我们可以做的是引发RuntimeError
def shutdown():
raise RuntimeError("Server going down")
and catch that when app.run()
returns:
并在app.run()返回时捕获:
...
try:
app.run(host="0.0.0.0")
except RuntimeError, msg:
if str(msg) == "Server going down":
pass # or whatever you want to do when the server goes down
else:
# appropriate handling/logging of other runtime errors
# and so on
...
No need to send yourself a request.
无需向您发送请求。
#1
51
If you are just running the server on your desktop, you can expose an endpoint to kill the server (read more at Shutdown The Simple Server):
如果您只是在桌面上运行服务器,则可以公开端点以终止服务器(在关闭简单服务器时阅读更多信息):
from flask import request
def shutdown_server():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
@app.route('/shutdown', methods=['POST'])
def shutdown():
shutdown_server()
return 'Server shutting down...'
Here is another approach that is more contained:
这是另一种更加包含的方法:
from multiprocessing import Process
server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()
Let me know if this helps.
如果这有帮助,请告诉我。
#2
12
I did it slightly different using threads
我使用线程做的略有不同
from werkzeug.serving import make_server
class ServerThread(threading.Thread):
def __init__(self, app):
threading.Thread.__init__(self)
self.srv = make_server('127.0.0.1', 5000, app)
self.ctx = app.app_context()
self.ctx.push()
def run(self):
log.info('starting server')
self.srv.serve_forever()
def shutdown(self):
self.srv.shutdown()
def start_server():
global server
app = flask.Flask('myapp')
...
server = ServerThread(app)
server.start()
log.info('server started')
def stop_server():
global server
server.shutdown()
I use it to do end to end tests for restful api, where I can send requests using the python requests library.
我使用它来为restful api做端到端测试,我可以使用python请求库发送请求。
#3
5
My method can be proceeded via bash terminal/console
我的方法可以通过bash终端/控制台进行
1) run and get the process number
1)运行并获取进程号
$ ps aux | grep yourAppKeywords
2a) kill the process
2a)杀死进程
$ kill processNum
2b) kill the process if above not working
2b)如果上面没有工作就杀了这个过程
$ kill -9 processNum
#4
4
As others have pointed out, you can only use werkzeug.server.shutdown
from a request handler. The only way I've found to shut down the server at another time is to send a request to yourself. For example, the /kill
handler in this snippet will kill the dev server unless another request comes in during the next second:
正如其他人指出的那样,您只能从请求处理程序中使用werkzeug.server.shutdown。我发现在另一个时间关闭服务器的唯一方法是向自己发送请求。例如,此代码段中的/ kill处理程序将终止开发服务器,除非在下一秒内有另一个请求进入:
import requests
from threading import Timer
import time
LAST_REQUEST_MS = 0
@app.before_request
def update_last_request_ms():
global LAST_REQUEST_MS
LAST_REQUEST_MS = time.time() * 1000
@app.route('/seriouslykill', methods=['POST'])
def seriouslykill():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
return "Shutting down..."
@app.route('/kill', methods=['POST'])
def kill():
last_ms = LAST_REQUEST_MS
def shutdown():
if LAST_REQUEST_MS <= last_ms: # subsequent requests abort shutdown
requests.post('http://localhost:5000/seriouslykill')
else:
pass
Timer(1.0, shutdown).start() # wait 1 second
return "Shutting down..."
#5
2
This is an old question, but googling didn't give me any insight in how to accomplish this.
这是一个老问题,但谷歌搜索没有给我任何洞察力如何实现这一目标。
Because I didn't read the code here properly! (Doh!) What it does is to raise a RuntimeError
when there is no werkzeug.server.shutdown
in the request.environ
...
因为我没有在这里正确阅读代码! (Doh!)它的作用是在request.environ中没有werkzeug.server.shutdown时引发RuntimeError ...
So what we can do when there is no request
is to raise a RuntimeError
所以当没有请求时我们可以做的是引发RuntimeError
def shutdown():
raise RuntimeError("Server going down")
and catch that when app.run()
returns:
并在app.run()返回时捕获:
...
try:
app.run(host="0.0.0.0")
except RuntimeError, msg:
if str(msg) == "Server going down":
pass # or whatever you want to do when the server goes down
else:
# appropriate handling/logging of other runtime errors
# and so on
...
No need to send yourself a request.
无需向您发送请求。