forked from orbit-oss/flask
Added appfactory pattern
This commit is contained in:
parent
182ee31503
commit
02b916d509
2 changed files with 74 additions and 0 deletions
73
docs/patterns/appfactories.rst
Normal file
73
docs/patterns/appfactories.rst
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
Application Factories
|
||||
=====================
|
||||
|
||||
If you are already using packages and modules for your application
|
||||
(:ref:`packages`) there are couple of really nice ways to further improve
|
||||
the experience. A common pattern is creating the application object when
|
||||
the module is imported. But if you move the creation of this object,
|
||||
into a function, you can then create multiple instances of this and later.
|
||||
|
||||
So why would you want to do this?
|
||||
|
||||
1. Testing. You can have instances of the application with different
|
||||
settings to test every case.
|
||||
2. 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.
|
||||
|
||||
So how would you then actually implement that?
|
||||
|
||||
Basic Factories
|
||||
---------------
|
||||
|
||||
The idea is to set up the application in a function. Like this::
|
||||
|
||||
def create_app(config_filename):
|
||||
app = Flask(__name__)
|
||||
app.config.from_pyfile(config_filename)
|
||||
|
||||
from yourapplication.views.admin import admin
|
||||
from yourapplication.views.frontend import frontend
|
||||
app.register_module(admin)
|
||||
app.register_module(frontend)
|
||||
|
||||
return app
|
||||
|
||||
The downside is that you cannot use the application object in the modules
|
||||
at import time. You can however use it from within a request. How do you
|
||||
get access the application with the config? Use
|
||||
:data:`~flask.current_app`::
|
||||
|
||||
from flask import current_app, Module, render_template
|
||||
admin = Module(__name__, url_prefix='/admin')
|
||||
|
||||
@admin.route('/')
|
||||
def index():
|
||||
return render_template(current_app.config['INDEX_TEMPLATE'])
|
||||
|
||||
Here we look up the name of a template in the config.
|
||||
|
||||
Using Applications
|
||||
------------------
|
||||
|
||||
So to use such an application you then have to create the application
|
||||
first. Here an example `run.py` file that runs such an application::
|
||||
|
||||
from yourapplication import create_app
|
||||
app = create_app('/path/to/config.cfg')
|
||||
app.run()
|
||||
|
||||
Factory Improvements
|
||||
--------------------
|
||||
|
||||
The factory function from above is not very clever so far, you can improve
|
||||
it. The following changes are straightforward and possible:
|
||||
|
||||
1. make it possible to pass in configuration values for unittests so that
|
||||
you don't have to create config files on the filesystem
|
||||
2. call a function from a module when the application is setting up so
|
||||
that you have a place to modify attributes of the application (like
|
||||
hooking in before / after request handlers etc.)
|
||||
3. Add in WSGI middlewares when the application is creating if necessary.
|
||||
|
|
@ -17,6 +17,7 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_.
|
|||
:maxdepth: 2
|
||||
|
||||
packages
|
||||
appfactories
|
||||
distribute
|
||||
sqlite3
|
||||
sqlalchemy
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue