简体   繁体   English

使用 uWSGI 运行 flask 应用程序

[英]Run flask application with uWSGI

I have a flask application and I would like to run it in a "production" way using uwsgi.我有一个 flask 应用程序,我想使用 uwsgi 以“生产”方式运行它。

I have my launcher.py :我有我的launcher.py

from app import app
import db

if __name__ == "__main__":
    db.init()
    app.run()

If I run the application with simply python launcher.py it's all ok.如果我只使用python launcher.py运行应用程序,一切都可以。 Especially, the db.init() is called correctly.特别是,正确调用了db.init()

However, if I run using uwgsi with uwsgi app.ini , db.init() is not called.但是,如果我使用 uwgsi 和uwsgi app.ini运行,则不会调用db.init()

Here is app.ini :这是app.ini

[uwsgi]
wsgi-file = launcher.py
callable = app
socket = :8080

I'm new with flask and uwsgi so probably I missed something but I could not find the solution in the different tutorials I read.我是 flask 和 uwsgi 的新手,所以可能我错过了一些东西,但我在阅读的不同教程中找不到解决方案。

Also, in case you need it to understand the project, here is app.py :另外,如果您需要它来理解项目,这里是app.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "hello from flask"

if __name__ == "__main__":
    db.init()
    app.run()

All files are in the same level in my project:我的项目中的所有文件都在同一级别:

webserver/
    - app.ini
    - launcher.py
    - app.py
    - db.py

So, what am I doing wrong here?那么,我在这里做错了什么?

Your code under if __name__ == "__main__": is not executed because uwsgi does not run your script like python app.py . if __name__ == "__main__":下的代码未执行,因为uwsgi不会像python app.py那样运行您的脚本。 Instead it imports the module specified in wsgi-file and looks for an object specified as callable (app in our case).相反,它导入wsgi-file中指定的模块并查找指定为callable的 object(在我们的例子中是应用程序)。 You can test it by using the following script:您可以使用以下脚本对其进行测试:

from flask import Flask

app = Flask(__name__)

print(__name__)
if __name__ == '__main__':
    app.run()

If you run it with python./flask_app.py then the output will be如果您使用python./flask_app.py运行它,那么 output 将是

$ 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)

(notice __main__ - it means we're running the script). (注意__main__ - 这意味着我们正在运行脚本)。 However if you run it with uwsgi the __name__ will be app (it will be the name of your file, so app in my case):但是,如果您使用__name__ uwsgiapp (它将是您的文件名,在我的情况下是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)

Similar output will be if you run your app with FLASK_APP=app flask run - it does not execute script, it just imports it and uses app object from it.如果您使用FLASK_APP=app flask run - 它不执行脚本,它只是导入它并使用它的app object。

So, in order to initialize database you should either move your db initialization out of if __name__ == "__main__" :因此,为了初始化数据库,您应该将数据库初始化移出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()

Or add a before_first_request handler:或者添加一个before_first_request处理程序:

# replace db.init() with 
@app.before_first_request
def init_db():
    db.init()

Notice the difference between them - if you put db.init() as a top-level statement it will be executed once you load app.py .请注意它们之间的区别 - 如果您将db.init()作为顶级语句,它将在您加载app.py后执行。 If you register a before_first_request callback it will be executed once first request arrives to your application.如果您注册了before_first_request回调,它将在第一个请求到达您的应用程序时执行。 Pick the one that works best for you.选择最适合您的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM