Jul*_* A. 17 python flask gunicorn
我正在使用Flask的内置开发服务器开发Flask应用程序.我是用Flask-Script开始的.我想切换到使用Gunicorn作为Web服务器.为此,我需要在Flask-Script和Gunicorn之间编写某种集成代码吗?或者Flask-Script与使用Gunicorn运行应用程序无关?
提前致谢!
道具到@ sean-lynch.以下是基于他的答案的工作,测试代码.我所做的改变是:
在尝试启动服务器之前,将从sys.argv
中删除Gunicorn无法识别的选项remove_non_gunicorn_command_line_args()
.否则Gunicorn会抛出一条错误,上面写着这样的信息:error: unrecognized arguments: --port 5010
.我删除-p
因为,即使它不会导致错误,这只是因为Gunicorn认为它的pidfile
选项的缩写形式,这显然不是预期的.
修改了GunicornServer.handle()签名以匹配它覆盖的方法,即Command.handle()
-
from flask_script import Command
from gunicorn.app.base import Application
class GunicornServer(Command):
description = 'Run the app within Gunicorn'
def __init__(self, host='127.0.0.1', port=8000, workers=6):
self.port = port
self.host = host
self.workers = workers
def get_options(self):
return (
Option('-t', '--host',
dest='host',
default=self.host),
Option('-p', '--port',
dest='port',
type=int,
default=self.port),
Option('-w', '--workers',
dest='workers',
type=int,
default=self.workers),
)
def handle(self, app, *args, **kwargs):
host = kwargs['host']
port = kwargs['port']
workers = kwargs['workers']
def remove_non_gunicorn_command_line_args():
import sys
args_to_remove = ['--port','-p']
def args_filter(name_or_value):
keep = not args_to_remove.count(name_or_value)
if keep:
previous = sys.argv[sys.argv.index(name_or_value) - 1]
keep = not args_to_remove.count(previous)
return keep
sys.argv = filter(args_filter, sys.argv)
remove_non_gunicorn_command_line_args()
from gunicorn import version_info
if version_info < (0, 9, 0):
from gunicorn.arbiter import Arbiter
from gunicorn.config import Config
arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)),'workers': workers}), app)
arbiter.run()
else:
class FlaskApplication(Application):
def init(self, parser, opts, args):
return {
'bind': '{0}:{1}'.format(host, port),
'workers': workers
}
def load(self):
return app
FlaskApplication().run()
manager.add_command('gunicorn', GunicornServer())
Run Code Online (Sandbox Code Playgroud)
Sea*_*nch 14
正如Dhaivat所说,你可以直接使用你的Flask应用程序与Gunicorn.
如果您仍想使用Flask-Script,则需要创建自定义Command
.我对Gunicorn没有任何经验,但我找到了类似Flask-Actions的解决方案并将其移植到Flask-Script,虽然被警告,但它未经测试.
from flask_script import Command, Option
class GunicornServer(Command):
description = 'Run the app within Gunicorn'
def __init__(self, host='127.0.0.1', port=8000, workers=4):
self.port = port
self.host = host
self.workers = workers
def get_options(self):
return (
Option('-H', '--host',
dest='host',
default=self.host),
Option('-p', '--port',
dest='port',
type=int,
default=self.port),
Option('-w', '--workers',
dest='workers',
type=int,
default=self.workers),
)
def handle(self, app, host, port, workers):
from gunicorn import version_info
if version_info < (0, 9, 0):
from gunicorn.arbiter import Arbiter
from gunicorn.config import Config
arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)),'workers': workers}), app)
arbiter.run()
else:
from gunicorn.app.base import Application
class FlaskApplication(Application):
def init(self, parser, opts, args):
return {
'bind': '{0}:{1}'.format(host, port),
'workers': workers
}
def load(self):
return app
FlaskApplication().run()
Run Code Online (Sandbox Code Playgroud)
然后,您可以注册它来代替瓶的本地开发服务器在python manage.py runserver
manager.add_command("runserver", GunicornServer())
Run Code Online (Sandbox Code Playgroud)
或注册为新命令,如 python manage.py gunicorn
manager.add_command("gunicorn", GunicornServer())
Run Code Online (Sandbox Code Playgroud)
编辑2016年6月:随着瓶脚本的最新版本,改变方法handle
有__call__
.旧烧瓶脚本与新烧瓶脚本
我写了一个基于肖恩林奇的更好版本的GunicornServer,该命令现在接受所有gunicorn的论点
from yourapp import app
from flask.ext.script import Manager, Command, Option
class GunicornServer(Command):
"""Run the app within Gunicorn"""
def get_options(self):
from gunicorn.config import make_settings
settings = make_settings()
options = (
Option(*klass.cli, action=klass.action)
for setting, klass in settings.iteritems() if klass.cli
)
return options
def run(self, *args, **kwargs):
from gunicorn.app.wsgiapp import WSGIApplication
app = WSGIApplication()
app.app_uri = 'manage:app'
return app.run()
manager = Manager(app)
manager.add_command("gunicorn", GunicornServer())
Run Code Online (Sandbox Code Playgroud)
根据Sean的回答,我还写了一个我更喜欢的版本。
@manager.option('-h', '--host', dest='host', default='127.0.0.1')
@manager.option('-p', '--port', dest='port', type=int, default=6969)
@manager.option('-w', '--workers', dest='workers', type=int, default=3)
def gunicorn(host, port, workers):
"""Start the Server with Gunicorn"""
from gunicorn.app.base import Application
class FlaskApplication(Application):
def init(self, parser, opts, args):
return {
'bind': '{0}:{1}'.format(host, port),
'workers': workers
}
def load(self):
return app
application = FlaskApplication()
return application.run()
Run Code Online (Sandbox Code Playgroud)
你可以使用这样的命令运行gunicornpython manager.py gunicorn