【问题标题】:Auto reloading Flask app when source code changes源代码更改时自动重新加载 Flask 应用程序
【发布时间】:2014-06-17 12:17:43
【问题描述】:

我知道 Flask 在调试模式下会检测到对 .py 源代码文件的更改,并会在新请求进入时重新加载它们。

我过去常常在我的应用程序中看到这个。在我的views.py 文件的@app.route 装饰部分中更改一些文本,刷新后我可以在浏览器中看到更改。

但是突然之间(不记得发生了什么变化),这似乎不再起作用了。

问:我哪里出错了?

我在 OSX 10.9 系统上运行,并使用 Python 2.7 进行了 VENV 设置。我在我的项目根目录中使用foreman start 来启动它。

应用结构是这样的:

[Project Root]
+-[app]
| +-__init__.py
| +- views.py
| +- ...some other files...
+-[venv]
+- config.py
+- Procfile
+- run.py

文件如下所示:

# Procfile
web: gunicorn --log-level=DEBUG run:app
# config.py
contains some app specific configuration information.
# run.py
from app import app

if __name__ == "__main__":
    app.run(debug = True, port = 5000)
# __init__.py
from flask import Flask
from flask.ext.login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.mail import Mail
import os

app = Flask(__name__)
app.config.from_object('config')

db = SQLAlchemy(app)

#mail sending
mail = Mail(app)

lm = LoginManager()
lm.init_app(app)
lm.session_protection = "strong"

from app import views, models
# app/views.py
@app.route('/start-scep')
def start_scep():
    startMessage = '''\
<html>
<header>
<style>
body { margin:40px 40px;font-family:Helvetica;}
h1 { font-size:40px; }
p { font-size:30px; }
a { text-decoration:none; }
</style>
</header>

<p>Some text</p>
</body>
</html>\
'''
    response = make_response(startMessage)
    response.headers['Content-Type'] = "text/html"
    print response.headers
    return response

【问题讨论】:

  • @SeanVieira 我在命令行中使用foreman start。我应该做foreman run python run.py吗?
  • 是的,这就是您想要做的(很可能)——如果这不起作用,请改用python run.py

标签: python flask foreman


【解决方案1】:

正如其他答案所述,这里的问题是您似乎从 python run.py 移动到 foreman start,或者您将 Procfile 更改为

# Procfile
web: python run.py

# Procfile
web: gunicorn --log-level=DEBUG run:app

当您运行foreman start 时,它只会运行您在Procfile 中指定的命令。 (我猜你正在使用 Heroku,但即使没有,这也很好,因为它会模仿将在你的服务器/Heroku dyno/任何东西上运行的内容。)

所以现在,当您运行gunicorn --log-level=DEBUG run:app(通过foreman start)时,您现在正在使用gunicorn 运行您的应用程序,而不是Flask 附带的内置网络服务器。 run:app 参数告诉 gunicornrun.py 中查找名为 Flask 的实例 app,导入并运行它。这就是有趣的地方:因为run.py 正在被导入,__name__ == '__main__'False(请参阅here 的更多信息),因此永远不会调用app.run(debug = True, port = 5000)

这就是您想要的(至少在公开可用的设置中),因为在调用app.run() 时使用的Flask 内置的网络服务器存在一些非常严重的安全漏洞。 --log-level=DEBUG 也可能有点欺骗性,因为它使用了“DEBUG”这个词,但它只是告诉 gunicorn 要打印哪些日志语句以及忽略哪些日志语句(查看 Python docs on logging。)

解决方案是在本地运行应用程序并对其进行工作/调试时运行python run.py,并且仅在您想模拟生产环境时运行foreman start。另外,由于gunicorn 只需要导入app 对象,您可以消除一些歧义并将您的Procfile 更改为

# Procfile
web: gunicorn --log-level=DEBUG app:app

您还可以查看 Flask Script,它有一个内置命令 python manage.py runserver,它以调试模式运行内置的 Flask 网络服务器。

【讨论】:

    【解决方案2】:

    解决办法是按照cmets中的说明停止使用foreman start,直接执行python run.py

    这样,带有debug=Trueuse_reloader=True配置参数的app.run方法生效。

    【讨论】:

      【解决方案3】:

      示例应用程序,其中 app 是我们的应用程序,并且此应用程序已保存在文件 start.py 中:

      from flask import Flask
      app = Flask(__name__)
      
      @app.route('/')
      def hallo():
          return 'Hello World, this is really cool... that rocks... LOL'
      

      现在我们从带有 --reload

      标志的 shell 启动应用程序
      gunicorn -w 1 -b 127.0.0.1:3032 start:app --reload
      

      gunicorn 会在文件自动更改时重新加载应用程序。根本不需要改变任何东西。

      如果您想在后台运行此应用程序,请添加标志 -D

      gunicorn -D -w 1 -b 127.0.0.1:3032 start:app --reload
      

      -D 恶魔模式

      -w 工人数

      -b 地址和端口

      开始(start.py):app - 应用程序

      --reload gunicorns 文件监控

      查看设置文件: http://docs.gunicorn.org/en/latest/settings.html

      那里提到了所有选项和标志。玩得开心!

      【讨论】:

      猜你喜欢
      • 2013-04-27
      • 1970-01-01
      • 2011-10-10
      • 2015-12-09
      • 1970-01-01
      • 2012-03-19
      • 2013-04-05
      相关资源
      最近更新 更多