Search code examples
pythonflaskflask-script

Run code after flask application has started


My goal is to get arbitrary code to run after my Flask application is started. Here is what I've got:

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

Ideally I would be able to just do this:

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

But the code doesn't continue past app.run(), so some_code() never runs.

The solution I'm working on at the moment is to run some_code() in a separate thread from app.run(), create a before first request function that sets this:

app.is_running = True

Then get some_code() to shoot a basic request to app so that the 'before first request' code runs. This is fairly convoluted and going to be hard to document. I would rather use app.is_running parameter which already is provided in Flask, or use a @app.after_server_start decorator, but to my knowledge neither of those exists.

Help me make this code better?


Posthumous: Every time I think about this issue, it makes me wish that a @app.after_server_start decorator existed.


Solution

  • 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.