smurfix/flask-script

flask-script should support init_app() pattern

chancez opened this issue · 8 comments

It would be really handy instead of requiring the flask "App" object at manager creation time, if this could be deferred until later, by using the init_app() pattern.

http://flask.pocoo.org/docs/0.10/patterns/appfactories/

The basic would be any add_* command, or something which registers would check if self.app is None, and if it is, you add it to a list. Then manager.init_app(app) would go through each list and actually do the registration.

Pleaseee!

👍

I would love to see this
+1

I don't think flask-script should do that. The init_app pattern comes in handy for extensions, but does not make any sense for an application that takes such an external role.

The steps

  1. Create a Flask() object
  2. Register all extensions using ext.init_app()
  3. Run the app and benefit from the functionality of the extension (e.g. Babel)

Step three is definitely not the use case of flask_script: The most you do is to call app.run() to provide a run function providing a certain setup, but you never provide anything that needs to be accessible at runtime.

flask_script is an external helper, but nothing which provides inside functionality to the running app.

If you are using the application factory pattern, most probably you will have this extension instantiated in a dedicated module. Just for this pattern, it is useful to be able to call the init_app method.

I'm with @lukasjuhrich on this one. Plus, overloading the init_app concept to mean either "initialize the given extention" or "initialize all extentions" would cause additional confusion for everybody, especially those new to flask-script.

A beginner to flask-script would probably get hung up trying to do something like this

def create_app(config):
    ....
    pages.init_app(app)
    bootstrap.init_app(app)
    manager.init_app(app)
    ...
    return app

which would be incorrect since the proposal is to have manager.init_app(app) calling every other init_app(app).

Please correct me if I've misunderstood the original intent behind this issue, this was how I interpreted it.

I also recently found out that you actually can, in fact, delay the creation of the app object until later, but not via the init_app pattern. This gist by smurfix describes how you can avoid the need to use an initialized app to create the Manager and make use of your already existing app factory (assuming your project is layed out such that there is one). The creation of a manager then becomes (taken from the gist snippet)

from app import create_app

manager = Manager(create_app)
manager.add_option('-c', '--config', dest='config', required=False)
...
manager.run()
app = create_app(config_name)

...
...

manager.app = app

should do the trick