Run code after flask application has started
If you need to execute some code after your flask application is started but strictly before the first request, not even be triggered by the execution of the first request as @app.before_first_request can handle, you should use Flask_Script, as CESCO said, but you could subclass the class Server and overwrite the __ call __ method, instead of overwriting the runserver command with @manager.command:
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()
This way you don't override default options of runserver command.
I don't really like any of the methods mentioned above, for the fact that you don't need Flask-Script to do this, and not all projects are going to use Flask-Script already.
The easiest method, would be to build your own Flask sub-class. Where you construct your app with Flask(__name__)
, you would simply add your own class and use it instead.
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()
Of course, this doesn't run after it starts, but right before run()
is finally called. With app context, you should be able to do anything you may need to do with the database or anything else requiring app context. This should work with any server (uwsgi, gunicorn, etc.) as well.
If you need the do_something()
to be non-blocking, you can simply thread it with threading.Thread(target=do_something).start()
instead.
The conditional statement is to prevent the double call when using debug mode/reloader.