2016-06-07 4 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 

내용은이 값

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

I을 포함 gunicorn -b 0.0.0.0:9000 --access-logfile - "app.hello:create_app()"을 사용하여 gunicorn으로이 작업을 성공적으로 실행할 수 있으며 오류없이 작동합니다.

그러나 루트에서 python app/hello.py을 실행하면 ImportError: No module named 'config' 오류가 발생합니다. 이 방식으로 실행하면 플라스크가 config 디렉토리를 찾을 수없는 것 같습니다.

config 디렉토리를 app 안에 옮길 수 있지만 그렇게하면 대신 gunicorn에 오류가 발생할 수 있습니다. 두 가지 방법 모두 "일하는 것"이 ​​가능하지 않습니까? 무엇보다 중요한 이유는 무엇입니까?

+1

config에'__init __. py' 파일을 추가하여 패키지로 만드시겠습니까? – syntonym

+0

이전에'config /'에 빈'__init __. py '를 추가하려고했으나 도움이되지 않았습니다. 같은 오류가 발생합니다. – peonicles

+0

config.settings를 수동으로 가져온 다음 from_object (config.settings)를 사용하여 가져올 수 있습니다. 어쩌면 gunicorn이 PYTHONPATH를 어떻게 든 조작합니다. config.settings를 가져올 수 있도록 pythonpath에 폴더를 추가 할 수 있습니다. (manully importing은 아무것도 변경하지 않아야한다. 그러나 설정 모듈을 import 할 수 없다는 것을 probaly하면 알 수있다.) – 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 '에 있어야합니다.경로 '를 선택합니다. –

관련 문제