运行 带有 uWSGI 的烧瓶应用程序
Run flask application with uWSGI
我有一个 Flask 应用程序,我想 运行 使用 uwsgi 以“生产”方式使用它。
我有我的 launcher.py
:
from app import app
import db
if __name__ == "__main__":
db.init()
app.run()
如果我 运行 应用程序只需 python launcher.py
就可以了。特别是 db.init()
被正确调用。
但是,如果我 运行 将 uwgsi 与 uwsgi app.ini
一起使用,则不会调用 db.init()
。
这里是app.ini
:
[uwsgi]
wsgi-file = launcher.py
callable = app
socket = :8080
我是 flask 和 uwsgi 的新手,所以我可能错过了一些东西,但我在阅读的不同教程中找不到解决方案。
此外,如果您需要它来了解项目,这里是 app.py
:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "hello from flask"
if __name__ == "__main__":
db.init()
app.run()
所有文件在我的项目中都处于同一级别:
webserver/
- app.ini
- launcher.py
- app.py
- db.py
那么,我做错了什么?
您在 if __name__ == "__main__":
下的代码未执行,因为 uwsgi
不像 python app.py
那样 运行 您的脚本。相反,它导入在 wsgi-file
中指定的模块并查找指定为 callable
的对象(在我们的例子中是应用程序)。您可以使用以下脚本对其进行测试:
from flask import Flask
app = Flask(__name__)
print(__name__)
if __name__ == '__main__':
app.run()
如果你 运行 它与 python ./flask_app.py
那么输出将是
$ python ./flask_app.py
__main__
* Serving Flask app 'app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
(注意 __main__
- 这意味着我们正在 运行 脚本)。但是,如果你 运行 它与 uwsgi
一起 __name__
将是 app
(它将是你的文件的名称,所以在我的例子中是 app
):
$ uwsgi --http 127.0.0.1:5000 --module app:app
...
*** Operational MODE: single process ***
app
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7fb2d0c067b0 pid: 46794 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 46794, cores: 1)
如果您 运行 您的应用程序带有 FLASK_APP=app flask run
,则会出现类似的输出 - 它不执行脚本,它只是导入脚本并使用其中的 app
对象。
因此,为了初始化数据库,您应该将数据库初始化移出 if __name__ == "__main__"
:
from flask import Flask
app = Flask(__name__)
class DB:
def init(self):
self.data = 'Hello, World'
db = DB()
@app.route("/")
def hello_world():
return db.data
db.init()
if __name__ == '__main__':
app.run()
或添加一个 before_first_request
处理程序:
# replace db.init() with
@app.before_first_request
def init_db():
db.init()
请注意它们之间的区别 - 如果您将 db.init()
作为 top-level 语句放置,它将在您加载 app.py
后执行。如果您注册一个 before_first_request
回调,它将在第一个请求到达您的应用程序时执行。选择最适合您的一款。
我有一个 Flask 应用程序,我想 运行 使用 uwsgi 以“生产”方式使用它。
我有我的 launcher.py
:
from app import app
import db
if __name__ == "__main__":
db.init()
app.run()
如果我 运行 应用程序只需 python launcher.py
就可以了。特别是 db.init()
被正确调用。
但是,如果我 运行 将 uwgsi 与 uwsgi app.ini
一起使用,则不会调用 db.init()
。
这里是app.ini
:
[uwsgi]
wsgi-file = launcher.py
callable = app
socket = :8080
我是 flask 和 uwsgi 的新手,所以我可能错过了一些东西,但我在阅读的不同教程中找不到解决方案。
此外,如果您需要它来了解项目,这里是 app.py
:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "hello from flask"
if __name__ == "__main__":
db.init()
app.run()
所有文件在我的项目中都处于同一级别:
webserver/
- app.ini
- launcher.py
- app.py
- db.py
那么,我做错了什么?
您在 if __name__ == "__main__":
下的代码未执行,因为 uwsgi
不像 python app.py
那样 运行 您的脚本。相反,它导入在 wsgi-file
中指定的模块并查找指定为 callable
的对象(在我们的例子中是应用程序)。您可以使用以下脚本对其进行测试:
from flask import Flask
app = Flask(__name__)
print(__name__)
if __name__ == '__main__':
app.run()
如果你 运行 它与 python ./flask_app.py
那么输出将是
$ python ./flask_app.py
__main__
* Serving Flask app 'app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
(注意 __main__
- 这意味着我们正在 运行 脚本)。但是,如果你 运行 它与 uwsgi
一起 __name__
将是 app
(它将是你的文件的名称,所以在我的例子中是 app
):
$ uwsgi --http 127.0.0.1:5000 --module app:app
...
*** Operational MODE: single process ***
app
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7fb2d0c067b0 pid: 46794 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 46794, cores: 1)
如果您 运行 您的应用程序带有 FLASK_APP=app flask run
,则会出现类似的输出 - 它不执行脚本,它只是导入脚本并使用其中的 app
对象。
因此,为了初始化数据库,您应该将数据库初始化移出 if __name__ == "__main__"
:
from flask import Flask
app = Flask(__name__)
class DB:
def init(self):
self.data = 'Hello, World'
db = DB()
@app.route("/")
def hello_world():
return db.data
db.init()
if __name__ == '__main__':
app.run()
或添加一个 before_first_request
处理程序:
# replace db.init() with
@app.before_first_request
def init_db():
db.init()
请注意它们之间的区别 - 如果您将 db.init()
作为 top-level 语句放置,它将在您加载 app.py
后执行。如果您注册一个 before_first_request
回调,它将在第一个请求到达您的应用程序时执行。选择最适合您的一款。