2016-06-07 89 views
0

我使用烧瓶的virtualenv,和我的演示瓶的应用程序的结构如下:的hello.py为什么Flask的app.config.from_object()的行为与gunicorn不同?

from flask import Flask 


def create_app(): 
    app = Flask(__name__, instance_relative_config=True) 
    app.config.from_object("config.settings") 

    @app.route('/') 
    def index(): 
     return app.config["HELLO"] 

    return app 

if __name__ == "__main__": 
    app = create_app() 
    app.run() 

settings.py

app/ 
    hello.py 
config/ 
    settings.py 
venv/ 
    virtualenv files 

内容只包含2个值

DEBUG = True 
HELLO = "Hello there from /config !" 

我可以使用gunicorn -b 0.0.0.0:9000 --access-logfile - "app.hello:create_app()"与gunicorn成功运行,它的工作原理没有任何错误。

但是,从根目录运行python app/hello.py导致错误ImportError: No module named 'config'。看起来烧瓶在以这种方式执行时无法找到config目录。

我可以移动app内的config目录,但这样做会导致使用gunicorn出现错误。难道两种方式都不可能“只是工作”吗?更重要的是,为什么发生了什么?

+1

是否将'__init __。py'文件添加到config中,以便它是一个包,有帮助吗? – syntonym

+0

我曾尝试在'config /'中添加一个空的'__init __。py',但它没有帮助。发生同样的错误。 – peonicles

+0

您可以尝试手动导入config.settings,然后使用from_object(config.settings)。也许gunicorn确实操纵了PYTHONPATH。您可以尝试将您的文件夹添加到pythonpath,以便可以导入config.settings。 (手动导入不应该改变任何东西,但你可能会看到你无法导入设置模块。) – syntonym

回答

1

不是最优雅又不失完美的工作方案:

from os.path import abspath, join 
from flask import Flask 


def create_app(): 
    app = Flask(__name__, instance_relative_config=True) 
    config_file_path = abspath(
     join(app.instance_path, '../config/settings.py') 
    ) 
    app.config.from_pyfile(config_file_path) 

    @app.route('/') 
    def index(): 
     return app.config["HELLO"] 

    return app 


if __name__ == "__main__": 
    app = create_app() 
    app.run() 

此外,在考虑的评论之后。为了让Flask正确导入config.settings,应用程序根目录的路径必须位于sys.path之内。它可以很容易地通过在原剧本中添加一行来实现:

sys.path.insert(0, os.getcwd()) 

所以最后hello.py样子:

import os 
import sys 
from flask import Flask 


def create_app(): 
    app = Flask(__name__, instance_relative_config=True) 
    sys.path.insert(0, os.getcwd()) 
    app.config.from_object("config.settings") 

    @app.route('/') 
    def index(): 
     return app.config["HELLO"] 

    return app 


if __name__ == "__main__": 
    app = create_app() 
    app.run() 

更防弹解决方案是

app_root_path = os.path.abspath(
    os.path.join(app.instance_path, '..') 
) 
sys.path.insert(0, app_root_path) 

这种方式我们不依赖什么os.getcwd()返回:它并不总是必须返回应用程序根路径。

+0

后,我无法再现错误啊,我看到你在那里做了什么。很奇怪'os.getcwd()'实际上会返回应用根目录,但不知何故'app.config.from_object(“config.settings”)'不起作用。 – peonicles

+0

@peonicles您的评论让我明白了'os.getcwd()'必须位于'sys.path'中以便我们的导入工作。我编辑了我的答案来反映这个想法。 –

+0

更确切地说,应用程序的根路径必须位于sys。路径'为了导入工作。 –

相关问题