如何让Gunskcorn运行Flask应用

Wag*_*sUK 3 flask python-3.x

我是Flask / Python的新手,这个问题可能很愚蠢,或者我可能缺少明显的东西,所以请耐心等待。

我创建了一个Flask应用,其结构如下:

myproject
  api
    __init__.py
    api.py
    application.py
    config.py
    models.py
  migrations
    ...
  appserver.py
  manage.py
  Procfile
  requirements.txt
Run Code Online (Sandbox Code Playgroud)

我的内容appserver.py

from api.application import create_app

if __name__ == '__main__':
  create_app = create_app()
  create_app.run()
Run Code Online (Sandbox Code Playgroud)

我的内容api/application.py

from flask import Flask


def create_app(app_name='MYAPPNAME'):
  app = Flask(app_name)
  app.config.from_object('api.config.DevelopmentConfig')

  from api.api import api
  app.register_blueprint(api, url_prefix='/api')

  from api.models import db
  db.init_app(app)

  return app
Run Code Online (Sandbox Code Playgroud)

当我在本地运行服务器时,python appserver.py一切正常。当我尝试像这样运行gunicorn时:出现gunicorn --bind 127.0.0.1:5000 appserver:create_app此错误:TypeError: create_app() takes from 0 to 1 positional arguments but 2 were given

我在这里做错了什么?

Pra*_*kar 7

我建议您更新appserver.py文件内的代码,如下所示:

from api.application import create_app

if __name__ == '__main__':
    create_app = create_app()
    create_app.run()
else:
    gunicorn_app = create_app()
Run Code Online (Sandbox Code Playgroud)

然后如下运行该应用程序 gunicorn --bind 127.0.0.1:5000 appserver:gunicorn_app

执行上述步骤的原因如下:

在本地运行服务器

在本地运行服务器时python appserver.pyif将执行该块。因此,通过您的create_app方法创建了Flask对象,并且您能够访问服务器。

通过Gunicorn运行服务器

通过Gunicorn运行服务器时,需要指定模块名称和应用程序的变量名,以便Gunicorn访问它。请注意,该变量应该是WSGI可调用对象,例如flask应用程序对象。根据Gunicorn Docs中的定义。

运行Gunicorn命令时gunicorn --bind 127.0.0.1:5000 appserver:create_app,它会误create_app认为是WSGI可调用对象(Flask应用程序对象)。这引发了错误,因为create_app只是常规方法,该方法会在正确调用时返回Flask应用程序对象。

因此,我们在else块中添加了创建对象的部分,gunicorn_app = create_app()并通过Gunicorn使用gunicorn --bind 127.0.0.1:5000 appserver:gunicorn_app

您还需要注意的另一件事是,在运行块时会触发python appserver.pyif块,因为它是要执行的主文件。凡当你gunicorn --bind 127.0.0.1:5000 appserver:create_appappserver.py得到由gunicorn进口。因此,该else块被触发。这就是我们放置gunicorn_app = create_app()else块中。

我希望以上解释令人满意。如果您不了解任何部分,请告诉我。

  • @WagnerMatosUK 我已经更新了答案。如果您无法理解,请告诉我。很高兴答案有帮助。:) (2认同)

Ren*_*ira 6

Pranav Kundaikar 的回答非常好。我不知道他们是否更新了,gunicorn但我可以避免main使用以下方法在我的应用程序中添加:

gunicorn -w 4 'api:create_app()'
Run Code Online (Sandbox Code Playgroud)

  • 雷南·费雷拉 谢谢。您的解决方案的工作方式是,gunicorn 允许函数调用作为变量名称。该功能已于 2019 年 11 月添加。当我发布原始答案时,此功能不存在。我检查了一下,因为我想知道我是如何错过的。这是gunicorn的更改供参考 https://github.com/benoitc/gunicorn/commit/19cb68f4c3b55da22581c008659ee62d8c54ab2b 感谢分享此更新:) (3认同)
  • “-w 4”是无关紧要的,也许可以考虑将其从答案中删除,以免暗示需要它。 (2认同)