以下是我对如何执行此操作的建议。
1.如果需要以这种方式实例化,我不会依赖全局 server 变量。由于它是在应用程序创建后实例化的,因此最好以某种方式将其显式传递给应用程序。这样就可以从其他模块(blueprints、pluggable views等)访问,例如可以使用Flask的配置机制:
app.config['server'] = Server(f.read())
#...then in your view functions...
return app.config['server'].data
或者通过flask的globals object、g:
@app.before_request
def add_server_to_globals():
with open(sys.argv[1]) as f:
g.server = Server(f.read())
#...then in your view functions...
return g.server.data
或者通过继承 Flask 并通过初始化程序将其传入。
2. 现在您正在使用 gunicorn,您不能依赖 if __name__ == '__main__' 块,因为它仅在您运行文件时执行,而不是在导入文件时执行。 Gunicorn 通过导入应用程序对象(参见 how APP_MODULE is explained in the docs)并将其交给 gunicorn 的 WSGI 服务器来工作,因此您用于实例化 Server 的代码将不会运行。
unicorn 的另一个新要求是您不能依赖 sys.argv,因为这将是 gunicorn 的 sys.argv,这与您当前在直接运行文件时传入的任何参数都不同。
要替换if __name__ == '__main__' 块,您可以使用before_request,就像我在上面所做的那样,在应用程序处理其第一个请求之前运行一些代码。我建议使用环境变量或config file 将您的参数传递给Server 类。例如:
@app.before_request
def add_server_to_globals():
with open(os.environ['SERVER_FILE']) as f:
g.server = Server(f.read())
然后使用设置的环境变量运行您的应用程序:
$ SERVER_FILE=blah.txt gunicorn app:app
[2015-02-24 10:10:20 -0800] [3217] [INFO] Starting gunicorn 19.2.1
...
3.您还可以查看烧瓶文档中描述的"application factory" 模式来替换if __name__ == '__main__' 块。但在这种情况下,它不是很有必要。如果您只想实例化 Server 对象一次(出于性能原因),则应用程序工厂的用途是。
Here's some fully working code based on your example.
Here's another example using an application factory.