Added chapter about config
This commit is contained in:
parent
78fc9949aa
commit
182ee31503
5 changed files with 183 additions and 8 deletions
|
|
@ -289,3 +289,4 @@ Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
.. autoclass:: Config
|
.. autoclass:: Config
|
||||||
|
:members:
|
||||||
|
|
|
||||||
120
docs/config.rst
Normal file
120
docs/config.rst
Normal file
|
|
@ -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.
|
||||||
|
|
@ -14,6 +14,7 @@ web development.
|
||||||
tutorial/index
|
tutorial/index
|
||||||
testing
|
testing
|
||||||
errorhandling
|
errorhandling
|
||||||
|
config
|
||||||
shell
|
shell
|
||||||
patterns/index
|
patterns/index
|
||||||
deploying/index
|
deploying/index
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _distribute-deployment:
|
||||||
|
|
||||||
Deploying with Distribute
|
Deploying with Distribute
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
|
||||||
67
flask.py
67
flask.py
|
|
@ -641,21 +641,33 @@ class Config(dict):
|
||||||
app.config.from_pyfile('yourconfig.cfg')
|
app.config.from_pyfile('yourconfig.cfg')
|
||||||
|
|
||||||
Or alternatively you can define the configuration options in the
|
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
|
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
|
use the same module and with that provide the configuration values
|
||||||
just before the call::
|
just before the call::
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
SECRET_KEY = 'development key'
|
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),
|
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
|
only uppercase keys are added to the config. This makes it possible to use
|
||||||
config are however lowercased so they are converted for you. This makes
|
lowercase values in the config file for temporary values that are not added
|
||||||
it possible to use lowercase values in the config file for temporary
|
to the config or to define the config keys in the same file that implements
|
||||||
values that are not added to the config or to define the config keys in
|
the application.
|
||||||
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
|
:param root_path: path to which files are read relative from. When the
|
||||||
config object is created by the application, this is
|
config object is created by the application, this is
|
||||||
|
|
@ -667,10 +679,33 @@ class Config(dict):
|
||||||
dict.__init__(self, defaults or {})
|
dict.__init__(self, defaults or {})
|
||||||
self.root_path = root_path
|
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):
|
def from_pyfile(self, filename):
|
||||||
"""Updates the values in the config from a Python file. This function
|
"""Updates the values in the config from a Python file. This function
|
||||||
behaves as if the file was imported as module with the
|
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
|
:param filename: the filename of the config. This can either be an
|
||||||
absolute filename or a filename relative to the
|
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
|
#: application. In debug mode the debugger will kick in when an unhandled
|
||||||
#: exception ocurrs and the integrated server will automatically reload
|
#: exception ocurrs and the integrated server will automatically reload
|
||||||
#: the application if changes in the code are detected.
|
#: 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')
|
debug = ConfigAttribute('DEBUG')
|
||||||
|
|
||||||
#: if a secret key is set, cryptographic components can use this to
|
#: if a secret key is set, cryptographic components can use this to
|
||||||
#: sign cookies and other things. Set this to a complex random value
|
#: sign cookies and other things. Set this to a complex random value
|
||||||
#: when you want to use the secure cookie for instance.
|
#: 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')
|
secret_key = ConfigAttribute('SECRET_KEY')
|
||||||
|
|
||||||
#: The secure cookie uses this for the name of the session cookie
|
#: 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')
|
session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME')
|
||||||
|
|
||||||
#: A :class:`~datetime.timedelta` which is used to set the expiration
|
#: A :class:`~datetime.timedelta` which is used to set the expiration
|
||||||
#: date of a permanent session. The default is 31 days which makes a
|
#: date of a permanent session. The default is 31 days which makes a
|
||||||
#: permanent session survive for roughly one month.
|
#: 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')
|
permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME')
|
||||||
|
|
||||||
#: Enable this if you want to use the X-Sendfile feature. Keep in
|
#: 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.
|
#: sent with the :func:`send_file` method.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.2
|
#: .. 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')
|
use_x_sendfile = ConfigAttribute('USE_X_SENDFILE')
|
||||||
|
|
||||||
#: the logging format used for the debug logger. This is only used when
|
#: the logging format used for the debug logger. This is only used when
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue