2016-06-07 109 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。路徑'爲了導入工作。 –

相關問題