Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added chapter about config

  • Loading branch information...
commit 182ee31503ea8a9eefd0d7063bd7fbdde991e13b 1 parent 78fc994
@mitsuhiko authored
View
1  docs/api.rst
@@ -289,3 +289,4 @@ Configuration
-------------
.. autoclass:: Config
+ :members:
View
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.
View
1  docs/contents.rst.inc
@@ -14,6 +14,7 @@ web development.
tutorial/index
testing
errorhandling
+ config
shell
patterns/index
deploying/index
View
2  docs/patterns/distribute.rst
@@ -1,3 +1,5 @@
+.. _distribute-deployment:
+
Deploying with Distribute
=========================
View
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 @@ def __init__(self, root_path, defaults=None):
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 '
@sebest
sebest added a note

What is this '%r' ?
Maybe it should be %s and add % (variable_name) at the end of the error message

@sebest
sebest added a note

Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.6/dist-packages/flask.py", line 698, in from_envvar
raise RuntimeError('The environment variable %r is not set '
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

@mitsuhiko Owner

Will fix that and push out 0.3.1 today. I made a mistake with packaging too, so now i also got a bugfix :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ '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
@sebest

What is this '%r' ?
Maybe it should be %s and add % (variable_name) at the end of the error message

@sebest

Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.6/dist-packages/flask.py", line 698, in from_envvar
raise RuntimeError('The environment variable %r is not set '
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

@mitsuhiko

Will fix that and push out 0.3.1 today. I made a mistake with packaging too, so now i also got a bugfix :)

Please sign in to comment.
Something went wrong with that request. Please try again.