Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>According to the <a href="http://flask.pocoo.org/docs/patterns/appfactories/" rel="noreferrer">Flask Documentation</a>, an application factory is good because:</p> <blockquote> <ol> <li><p>Testing. You can have instances of the application with different settings to test every case.</p></li> <li><p>Multiple instances. Imagine you want to run different versions of the same application. Of course you could have multiple instances with different configs set up in your webserver, but if you use factories, you can have multiple instances of the same application running in the same application process which can be handy.</p></li> </ol> </blockquote> <p>But, as is stated in the <a href="http://flask.pocoo.org/docs/testing/#other-testing-tricks" rel="noreferrer">Other Testing Tricks</a> section of the documentation, if you're using application factories the functions <code>before_request()</code> and <code>after_request()</code> will be not automatically called.</p> <p>In the next paragraphs I will show how I've been using the application factory pattern with the uWSGI application server and nginx (I've only used those, but I can try to help you configure it with another server).</p> <h2>The Application Factory</h2> <p>So, let's say you have your application inside the folder <strong>yourapplication</strong> and inside it there's the <code>__init__.py</code> file:</p> <pre><code>import os from flask import Flask def create_app(cfg=None): app = Flask(__name__) load_config(app, cfg) # import all route modules # and register blueprints return app def load_config(app, cfg): # Load a default configuration file app.config.from_pyfile('config/default.cfg') # If cfg is empty try to load config file from environment variable if cfg is None and 'YOURAPPLICATION_CFG' in os.environ: cfg = os.environ['YOURAPPLICATION_CFG'] if cfg is not None: app.config.from_pyfile(cfg) </code></pre> <p>Now you need a file to create an instance of the app:</p> <pre><code>from yourapplication import create_app app = create_app() if __name__ == "__main__": app.run() </code></pre> <p>In the code above I'm assuming there's an environment variable set with the path to the config file, but you could give the config path to the factory, like this:</p> <pre><code>app = create_app('config/prod.cfg') </code></pre> <p>Alternatively, you could have something like a dictionary with environments and corresponding config files:</p> <pre><code>CONFIG_FILES = {'development': 'config/development.cfg', 'test' : 'config/test.cfg', 'production' : 'config/production.cfg' } </code></pre> <p>In this case, the <code>load_config</code> function would look like this:</p> <pre><code>def load_config(app, env): app.config.from_pyfile('config/default.cfg') var = "YOURAPPLICATION_ENV" if env is None and var in os.environ: env = os.environ[var] if env in CONFIG_FILES: app.config.from_pyfile(CONFIG_FILES[env]) </code></pre> <h2>Nginx and uWSGI</h2> <p>Here's an example of a configuration file for nginx:</p> <pre><code>server { listen 80; server_name yourapplication.com; access_log /var/www/yourapplication/logs/access.log; error_log /var/www/yourapplication/logs/error.log; location / { try_files $uri @flask; } location @flask { include uwsgi_params; uwsgi_pass unix:/tmp/yourapplication.sock; # /env is the virtualenv directory uwsgi_param UWSGI_PYHOME /var/www/yourapplication/env; # the path where the module run is located uwsgi_param UWSGI_CHDIR /var/www/yourapplication; # the name of the module to be called uwsgi_param UWSGI_MODULE run; # the variable declared in the run module, an instance of Flask uwsgi_param UWSGI_CALLABLE app; } } </code></pre> <p>And the uWSGI configuration file looks like this:</p> <pre><code>[uwsgi] plugins=python vhost=true socket=/tmp/yourapplication.sock env = YOURAPPLICATION_ENV=production logto = /var/www/yourapplication/logs/uwsgi.log </code></pre> <h2>How to use <code>before_request()</code> and <code>after_request()</code></h2> <p>The problem with those functions is that if your are calling them in other modules, those modules cannot be imported before the application has been instantiated. Again, the <a href="http://flask.pocoo.org/docs/patterns/appfactories/" rel="noreferrer">documentation</a> has something to say about that:</p> <blockquote> <p>The downside is that you cannot use the application object in the blueprints at import time. You can however use it from within a request. How do you get access to the application with the config? Use current_app:</p> </blockquote> <pre><code>from flask import current_app, Blueprint, render_template admin = Blueprint('admin', __name__, url_prefix='/admin') @admin.route('/') def index(): return render_template(current_app.config['INDEX_TEMPLATE']) </code></pre> <p>Or you could consider <a href="http://flask.pocoo.org/docs/extensiondev/#the-extension-code" rel="noreferrer">creating an extension</a>, then you could import the class without any existent instances of Flask, as the class extension would only use the Flask instance after being created.</p>
 

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