Browse Source

Added chapter about config

pull/1638/head
Armin Ronacher 15 years ago
parent
commit
182ee31503
  1. 1
      docs/api.rst
  2. 120
      docs/config.rst
  3. 1
      docs/contents.rst.inc
  4. 2
      docs/patterns/distribute.rst
  5. 67
      flask.py

1
docs/api.rst

@ -289,3 +289,4 @@ Configuration
-------------
.. autoclass:: Config
:members:

120
docs/config.rst

@ -0,0 +1,120 @@
Configuration Handling
======================
.. versionadded:: 0.5
Applications need some kind of configuration. There are different things
you might want to change. Like toggling debug mode, the secret key and a
lot of very similar things.
The way Flask is designed usually requires the configuration to be
available when the application starts up. You can either hardcode the
configuration in the code which for many small applications is not
actually that bad, but there are better ways.
Independent of how you load your config, there is a config object
available which holds the loaded configuration values:
The :attr:`~flask.Flask.config` attribute of the :class:`~flask.Flask`
object. This is the place where Flask itself puts certain configuration
values and also where extensions can put their configuration values. But
this is also where you can have your own configuration.
Configuration Basics
--------------------
The :attr:`~flask.Flask.config` is actually a subclass of a dictionary and
can be modified just like any dictionary::
app = Flask(__name__)
app.config['DEBUG'] = True
Certain configuration values are also forwarded to the
:attr:`~flask.Flask` object so that you can read and write them from
there::
app.debug = True
To update multiple keys at once you can use the :meth:`dict.update`
method::
app.config.update(
DEBUG=True,
SECRET_KEY='...'
)
Builtin Configuration Values
----------------------------
The following configuration values are used internally by Flask:
=============================== =========================================
``DEBUG`` enable/disable debug mode
``SECRET_KEY`` the secret key
``SESSION_COOKIE_NAME`` the name of the session cookie
``PERMANENT_SESSION_LIFETIME`` the lifetime of a permanent session as
:class:`datetime.timedelta` object.
``USE_X_SENDFILE`` enable/disable x-sendfile
=============================== =========================================
Configuring from Files
----------------------
Configuration becomes more useful if you can configure from a file. And
ideally that file would be outside of the actual application package that
you can install the package with distribute (:ref:`distribute-deployment`)
and still modify that file afterwards.
So a common pattern is this::
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
What this does is first loading the configuration from the
`yourapplication.default_settings` module and then overrides the values
with the contents of the file the :envvar:`YOURAPPLICATION_SETTINGS`
environment variable points to. This environment variable can be set on
Linux or OS X with the export command in the shell before starting the
server::
$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
$ python run-app.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader...
On Windows systems use the `set` builtin instead::
>set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
The configuration files themselves are actual Python files. Only values
in uppercase are actually stored in the config object later on. So make
sure to use uppercase letters for your config keys.
Here an example configuration file::
DEBUG = False
SECRET_KEY = '?\xbf,\xb4\x8d\xa3"<\x9c\xb0@\x0f5\xab,w\xee\x8d$0\x13\x8b83'
Make sure to load the configuration very early on so that extensions have
the ability to access the configuration when starting up. There are other
methods on the config object as well to load from individual files. For a
complete reference, read the :class:`~flask.Config` object's
documentation.
Configuration Best Practices
----------------------------
The downside with the approach mentioned earlier is that it makes testing
a little harder. There is no one 100% solution for this problem in
general, but there are a couple of things you can do to improve that
experience:
1. create your application in a function and register modules on it.
That way you can create multiple instances of your application with
different configurations attached which makes unittesting a lot
easier. You can use this to pass in configuration as needed.
2. Do not write code that needs the configuration at import time. If you
limit yourself to request-only accesses to the configuration you can
reconfigure the object later on as needed.

1
docs/contents.rst.inc

@ -14,6 +14,7 @@ web development.
tutorial/index
testing
errorhandling
config
shell
patterns/index
deploying/index

2
docs/patterns/distribute.rst

@ -1,3 +1,5 @@
.. _distribute-deployment:
Deploying with Distribute
=========================

67
flask.py

@ -641,21 +641,33 @@ class Config(dict):
app.config.from_pyfile('yourconfig.cfg')
Or alternatively you can define the configuration options in the
module that calls :meth:`from_module` or provide an import path to
module that calls :meth:`from_object` or provide an import path to
a module that should be loaded. It is also possible to tell it to
use the same module and with that provide the configuration values
just before the call::
DEBUG = True
SECRET_KEY = 'development key'
app.config.from_module(__name__)
app.config.from_object(__name__)
In both cases (loading from any Python file or loading from modules),
only uppercase keys are added to the config. The actual keys in the
config are however lowercased so they are converted for you. This makes
it possible to use lowercase values in the config file for temporary
values that are not added to the config or to define the config keys in
the same file that implements the application.
only uppercase keys are added to the config. This makes it possible to use
lowercase values in the config file for temporary values that are not added
to the config or to define the config keys in the same file that implements
the application.
Probably the most interesting way to load configurations is from an
environment variable pointing to a file::
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
In this case before launching the application you have to set this
environment variable to the file you want to use. On Linux and OS X
use the export statement::
export YOURAPPLICATION_SETTINGS='/path/to/config/file'
On windows use `set` instead.
:param root_path: path to which files are read relative from. When the
config object is created by the application, this is
@ -667,10 +679,33 @@ class Config(dict):
dict.__init__(self, defaults or {})
self.root_path = root_path
def from_envvar(self, variable_name, silent=False):
"""Loads a configuration from an environment variable pointing to
a configuration file. This basically is just a shortcut with nicer
error messages for this line of code::
app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])
:param variable_name: name of the environment variable
:param silent: set to `True` if you want silent failing for missing
files.
:return: bool. `True` if able to load config, `False` otherwise.
"""
rv = os.environ.get(variable_name)
if not rv:
if silent:
return False
raise RuntimeError('The environment variable %r is not set '
'and as such configuration could not be '
'loaded. Set this variable and make it '
'point to a configuration file')
self.from_pyfile(rv)
return True
def from_pyfile(self, filename):
"""Updates the values in the config from a Python file. This function
behaves as if the file was imported as module with the
:meth:`from_module` function.
:meth:`from_object` function.
:param filename: the filename of the config. This can either be an
absolute filename or a filename relative to the
@ -752,19 +787,32 @@ class Flask(_PackageBoundObject):
#: application. In debug mode the debugger will kick in when an unhandled
#: exception ocurrs and the integrated server will automatically reload
#: the application if changes in the code are detected.
#:
#: This attribute can also be configured from the config with the `DEBUG`
#: configuration key. Defaults to `False`.
debug = ConfigAttribute('DEBUG')
#: if a secret key is set, cryptographic components can use this to
#: sign cookies and other things. Set this to a complex random value
#: when you want to use the secure cookie for instance.
#:
#: This attribute can also be configured from the config with the
#: `SECRET_KEY` configuration key. Defaults to `None`.
secret_key = ConfigAttribute('SECRET_KEY')
#: The secure cookie uses this for the name of the session cookie
#:
#: This attribute can also be configured from the config with the
#: `SESSION_COOKIE_NAME` configuration key. Defaults to ``'session'``
session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME')
#: A :class:`~datetime.timedelta` which is used to set the expiration
#: date of a permanent session. The default is 31 days which makes a
#: permanent session survive for roughly one month.
#:
#: This attribute can also be configured from the config with the
#: `PERMANENT_SESSION_LIFETIME` configuration key. Defaults to
#: ``timedelta(days=31)``
permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME')
#: Enable this if you want to use the X-Sendfile feature. Keep in
@ -772,6 +820,9 @@ class Flask(_PackageBoundObject):
#: sent with the :func:`send_file` method.
#:
#: .. versionadded:: 0.2
#:
#: This attribute can also be configured from the config with the
#: `USE_X_SENDFILE` configuration key. Defaults to `False`.
use_x_sendfile = ConfigAttribute('USE_X_SENDFILE')
#: the logging format used for the debug logger. This is only used when

Loading…
Cancel
Save