我正在使用带有virtualenv的Flask,我的演示Flask应用程序的结构如下:
app/
hello.py
config/
settings.py
venv/
virtualenv files
hello.py
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
只包含2个值
DEBUG = True
HELLO = "Hello there from /config !"
我可以使用gunicorn -b 0.0.0.0:9000 --access-logfile - "app.hello:create_app()"
使用gunicorn成功运行此功能,它可以正常运行。
但是,从root运行python app/hello.py
会导致错误ImportError: No module named 'config'
。当以这种方式执行时,似乎烧瓶无法找到配置目录。
我可以在config
内移动app
目录,但这样做会导致gunicorn错误。难道两种方式都不可能“正常工作”吗?更重要的是,为什么以及发生了什么?
答案 0 :(得分:2)
不是最优雅但仍然完美的解决方案:
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
,app根目录的路径必须位于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()
返回的内容:它并不总是必须返回应用程序根路径。