启动Flask应用程序后运行代码

2024-04-29 09:12:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是在Flask应用程序启动后运行任意代码。以下是我所得到的:

def run():
    from webapp import app
    app.run(debug=True, use_reloader=False)

理想情况下,我可以这样做:

def run():
    from webapp import app
    app.run(debug=True, use_reloader=False)
    some_code()

但是代码不会在app.run()之后继续,因此某些代码()永远不会运行。

我目前正在研究的解决方案是,在app.run()的单独线程中运行一些_code(),创建一个before first request函数来设置:

app.is_running = True

然后获取一些_code()来向应用程序发送一个基本请求,以便运行“before first request”代码。这相当复杂,很难记录下来。我宁愿使用Flask中已经提供的app.is_running参数,或者使用@app.after_server_start装饰器,但据我所知,这两个都不存在。

帮我把代码做得更好?


死后:每次我想到这个问题,我都希望有一个@app.after_server_start装饰者存在。


Tags: run代码fromdebugimportfalsetrueapp
3条回答

如果您需要在flask应用程序启动后但严格地在第一个请求之前执行一些代码,甚至不会被执行第一个请求as@app触发。在第一个请求可以处理之前,您应该使用flask脚本,如CESCO所说,但是您可以将类服务器子类化并覆盖调用方法,而不是使用@manager.command覆盖runserver命令:

from flask import Flask
from flask_script import Manager, Server

def custom_call():
    #Your code
    pass

class CustomServer(Server):
    def __call__(self, app, *args, **kwargs):
        custom_call()
        #Hint: Here you could manipulate app
        return Server.__call__(self, app, *args, **kwargs)

app = Flask(__name__)
manager = Manager(app)

# Remeber to add the command to your Manager instance
manager.add_command('runserver', CustomServer())

if __name__ == "__main__":
    manager.run()

这样就不会覆盖runserver命令的默认选项。

使用Flask-Script运行应用程序,然后像这样覆盖runserver类/方法

# manage.py

from flask.ext.script import Manager

from myapp import app

manager = Manager(app)

def crazy_call():
    print("crazy_call")

@manager.command
def runserver():
    app.run()
    crazy_call()

if __name__ == "__main__":
    manager.run()

我不太喜欢上面提到的任何方法,因为您不需要Flask脚本来完成这项工作,而且并不是所有的项目都已经使用了Flask脚本。

最简单的方法,就是建立自己的烧瓶子类。在使用Flask(__name__)构建应用程序时,只需添加自己的类并使用它。

def do_something():
  print('MyFlaskApp is starting up!')


class MyFlaskApp(Flask):
  def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
    if not self.debug or os.getenv('WERKZEUG_RUN_MAIN') == 'true':
      with self.app_context():
        do_something()
    super(MyFlaskApp, self).run(host=host, port=port, debug=debug, load_dotenv=load_dotenv, **options)


app = MyFlaskApp(__name__)
app.run()

当然,这不会在启动后运行,但在最后调用run()之前运行。使用app context,您应该能够对数据库或其他需要app context的内容执行任何操作。这也适用于任何服务器(uwsgi、gunicorn等)。

如果您需要do_something()是非阻塞的,那么您可以用threading.Thread(target=do_something).start()来代替它。

条件语句是在使用调试模式/重载程序时防止双重调用。

相关问题 更多 >