我想通过使用flask-script来实现一个可以停止烧瓶应用的命令。 我已经搜索了一段时间的解决方案。因为框架不提供“app.stop()”API,所以我很好奇如何编写代码。我正在研究Ubuntu 12.10和Python 2.7.3。
答案 0 :(得分:71)
如果您只是在桌面上运行服务器,则可以公开端点以终止服务器(请阅读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...'
这是另一种更为受欢迎的方法:
from multiprocessing import Process
server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()
如果有帮助,请告诉我。
答案 1 :(得分:17)
我使用线程
略有不同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()
我用它来为restful api做端到端测试,我可以使用python请求库发送请求。
答案 2 :(得分:8)
我的方法可以通过bash终端/控制台进行
1)运行并获取进程号
$ ps aux | grep yourAppKeywords
2a)杀死进程
$ kill processNum
如果上面没有工作,2b)杀死进程
$ kill -9 processNum
答案 3 :(得分:7)
正如其他人所指出的那样,您只能使用请求处理程序中的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..."
答案 4 :(得分:4)
这是一个老问题,但谷歌搜索没有给我任何有关如何实现这一点的见解。
因为我没有正确阅读code here! (DOH!)
它的作用是在RuntimeError
中没有werkzeug.server.shutdown
时提出request.environ
...
所以当没有request
时,我们可以做的是提出RuntimeError
def shutdown():
raise RuntimeError("Server going down")
并在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
...
无需向自己发送请求。
答案 5 :(得分:4)
您不必按“ CTRL-C”,但是您可以提供一个为您做的端点:
from flask import Flask, jsonify, request
import json, os, signal
@app.route('/stopServer', methods=['GET'])
def stopServer():
os.kill(os.getpid(), signal.SIGINT)
return jsonify({ "success": True, "message": "Server is shutting down..." })
现在,您只需调用此端点即可正常关闭服务器:
curl localhost:5000/stopServer
答案 6 :(得分:2)
如果您使用的是CLI,并且仅运行一个Flask应用程序/进程(或者,您只是想杀死系统上运行的任何 Flask进程),则可以将其杀死:
kill $(pgrep -f flask)
答案 7 :(得分:1)
这是一个有点旧的线程,但是如果有人从后台运行的脚本开始尝试,学习或测试基本的flask应用,则停止它的最快方法是终止正在您端口上运行的进程运行您的应用程序。 注意:我知道作者正在寻找一种不杀死或停止该应用程序的方式。但这可能会对正在学习的人有所帮助。
sudo netstat -tulnp | grep :5001
您会得到类似的东西。
tcp 0 0 0.0.0.0:5001 0.0.0.0:* LISTEN 28834 / python
要停止应用,请终止进程
sudo kill 28834
答案 8 :(得分:1)
您可以使用下面的方法
Form
答案 9 :(得分:1)
如果您不在请求响应处理范围内,则仍然可以:
import os
import signal
sig = getattr(signal, "SIGKILL", signal.SIGTERM)
os.kill(os.getpid(), sig)
答案 10 :(得分:1)
如果其他人正在寻找如何在 win32服务中停止Flask服务器的方法-就在这里。这是几种方法的怪异组合,但效果很好。关键思想:
shutdown
端点,可用于正常关闭。 注意:它依赖于request.environ.get
,仅在Web请求的上下文(在@app.route
-ed函数内部)内可用。
SvcStop
方法使用requests
对服务本身进行HTTP请求。myservice_svc.py
import win32service
import win32serviceutil
import win32event
import servicemanager
import time
import traceback
import os
import myservice
class MyServiceSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "MyServiceSvc" # NET START/STOP the service by the following name
_svc_display_name_ = "Display name" # this text shows up as the service name in the SCM
_svc_description_ = "Description" # this text shows up as the description in the SCM
def __init__(self, args):
os.chdir(os.path.dirname(myservice.__file__))
win32serviceutil.ServiceFramework.__init__(self, args)
def SvcDoRun(self):
# ... some code skipped
myservice.start()
def SvcStop(self):
"""Called when we're being shut down"""
myservice.stop()
# tell the SCM we're shutting down
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
if __name__ == '__main__':
os.chdir(os.path.dirname(myservice.__file__))
win32serviceutil.HandleCommandLine(MyServiceSvc)
myservice.py
from flask import Flask, request, jsonify
# Workaround - otherwise doesn't work in windows service.
cli = sys.modules['flask.cli']
cli.show_server_banner = lambda *x: None
app = Flask('MyService')
# ... business logic endpoints are skipped.
@app.route("/shutdown", methods=['GET'])
def shutdown():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
if shutdown_func is None:
raise RuntimeError('Not running werkzeug')
shutdown_func()
return "Shutting down..."
def start():
app.run(host='0.0.0.0', threaded=True, port=5001)
def stop():
import requests
resp = requests.get('http://localhost:5001/shutdown')
答案 11 :(得分:0)
对于Windows,停止/杀死烧瓶服务器非常容易-
答案 12 :(得分:0)
我将Flask应用程序托管在Google Cloud Platform虚拟机上。
我使用python main.py
启动了应用程序,但问题是ctrl + c无法停止服务器。
此命令$ sudo netstat -tulnp | grep :5000
终止服务器。
默认情况下,我的Flask应用在端口5000上运行。
它适用于此。尚未针对其他平台进行测试。 如果它也适用于其他版本,请随时进行更新或评论。
答案 13 :(得分:0)
运行:python kill_server.py
。
这仅适用于 Windows 。通过PID并使用netstat收集的PID杀死具有taskkill的服务器。
# kill_server.py
import os
import subprocess
import re
port = 5000
host = '127.0.0.1'
cmd_newlines = r'\r\n'
host_port = host + ':' + str(port)
pid_regex = re.compile(r'[0-9]+$')
netstat = subprocess.run(['netstat', '-n', '-a', '-o'], stdout=subprocess.PIPE)
# Doesn't return correct PID info without precisely these flags
netstat = str(netstat)
lines = netstat.split(cmd_newlines)
for line in lines:
if host_port in line:
pid = pid_regex.findall(line)
if pid:
pid = pid[0]
os.system('taskkill /F /PID ' + str(pid))
# And finally delete the .pyc cache
os.system('del /S *.pyc')
如果您在使用favicon时遇到问题,也无法更改index.html的加载(即,已缓存旧版本),请在Chrome浏览器中尝试“清除浏览数据>图片和文件” 。 >
完成上述所有操作后,我终于在运行Flask应用程序时加载了我的收藏夹图标。