Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I use an app-factory in Flask / WSGI servers and why might it be unsafe?
    primarykey
    data
    text
    <h1>A question on app callables, WSGI servers and Flask circular imports</h1> <p>I am (possibly) confused. I want to safely create Flask / WSGI apps from app-factories and still be able to use them in WSGI servers easily.</p> <p>tl;dr</p> <ol> <li><p>Can I safely avoid creating an app on import of <strong>init</strong> (as recommended)and instead create it later (ie with a factory method)</p></li> <li><p>How do I make that app work neatly with a WSGI server? Especially when I am passing in the config and other settings not pulling them from ENV</p></li> </ol> <p>For example::</p> <pre><code>def make_app(configdict, appname): app = Flask(appname) app.config.update(configdict) init_db(configdict) set_app_in_global_namespace(app) #importing now will allow from pkg import app from mypackage import views return app </code></pre> <p>I would like to use the above "factory", because I want to easily contorl config for testing etc.</p> <p>I then presumably want to create a wsgi.py module that provides the app to a WSGI server.</p> <p>So eventually things look a bit like this</p> <p><strong>init</strong>.py::</p> <pre><code>app = None def make_app(configdict, appname): flaskapp = Flask(appname) flaskapp.config.update(configdict) init_db(configdict) global app app = flaskapp #importing now will allow from pkg import app from mypackage import views return flaskapp </code></pre> <p>wsgi.py::</p> <pre><code>from mypackage import app app = make_app(configfromsomewhere, "myname") </code></pre> <p>uWSGI::</p> <pre><code>uwsgi --module=mypackage.wsgi:app </code></pre> <p>But still wsgi.py is NOT something I can call like wsgi.py --settings=x --host=10.0.0.1 So I don't really know how to pass the config <em>in</em>. </p> <p>I am asking because while this seems ... OK ... it also is a bit messy. </p> <p>Life was easier when everything was in the ENV.</p> <p>And not only but also:</p> <h2>So what is unsafe about using an app-factory</h2> <p>The advice given <code>here &lt;http://flask.pocoo.org/docs/patterns/packages&gt;</code>_ is ::</p> <pre><code>1. the Flask application object creation has to be in the __init__.py file. That way each module can import it safely and the __name__ variable will resolve to the correct package. 2. all the view functions (the ones with a route() decorator on top) have to be imported in the __init__.py file. Not the object itself, but the module it is in. Import the view module after the application object is created. </code></pre> <p>re: 2., clearly the route decorator expects certain abilities from an instantiated app and cannot function without them. Thats fine.</p> <p>re: 1., OK we need the <strong>name</strong> correct. But what is unsafe ? And why? Is it unsafe to import and use the app if it is uninitialised? Well it will break but thats not unsafe. Is it the much vaunted thread-local? Possibly. But if I am plucking app instances willy-nilly from random modules I should expect trouble.</p> <p>Implications - we do not reference the app object from anything other than the views - essentially we keep our modularisation nice and tight, and pass around dicts, error objects, or even WebObs.</p> <p><a href="http://flask.pocoo.org/docs/patterns/appdispatch" rel="noreferrer">http://flask.pocoo.org/docs/patterns/appdispatch</a> <a href="http://flask.pocoo.org/docs/deploying/#deployment" rel="noreferrer">http://flask.pocoo.org/docs/deploying/#deployment</a> <a href="http://flask.pocoo.org/docs/patterns/packages/#larger-applications" rel="noreferrer">http://flask.pocoo.org/docs/patterns/packages/#larger-applications</a> <a href="http://flask.pocoo.org/docs/becomingbig" rel="noreferrer">http://flask.pocoo.org/docs/becomingbig</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload