summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMarcel Hellkamp <marc@gsites.de>2013-07-16 21:29:41 +0200
committerMarcel Hellkamp <marc@gsites.de>2013-07-16 21:29:41 +0200
commit5029b28f079275865ebe51491d98093286ebb2ca (patch)
tree2aa9c79f6ce418a5bb3fa15608a46b01543e8a95 /docs
parent642b5494bfae8fcabd856f9381fa561eb4ef2f4a (diff)
downloadbottle-5029b28f079275865ebe51491d98093286ebb2ca.tar.gz
Config docs
Diffstat (limited to 'docs')
-rw-r--r--docs/configuration.rst85
1 files changed, 56 insertions, 29 deletions
diff --git a/docs/configuration.rst b/docs/configuration.rst
index acc058d..b6d1d21 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -7,45 +7,45 @@ Configuration (DRAFT)
.. warning::
This is a draft for a new API. `Tell us <mailto:bottlepy@googlegroups.com>`_ what you think.
-Bottle applications can store their configuration in :attr:`Bottle.conf`, a dict-like object and central place for application specific settings. This dictionary controls many aspects of the framework, tells (newer) plugins what to do, and can be used to store your own configuration as well.
+Bottle applications can store their configuration in :attr:`Bottle.config`, a dict-like object and central place for application specific settings. This dictionary controls many aspects of the framework, tells (newer) plugins what to do, and can be used to store your own configuration as well.
Configuration Basics
====================
-The :attr:`Bottle.conf` object behaves a lot like an ordinary dictionary. All the common dict methods work as expected. Let us start with some examples::
+The :attr:`Bottle.config` object behaves a lot like an ordinary dictionary. All the common dict methods work as expected. Let us start with some examples::
import bottle
- app = bottle.default_app() # or bottle.Bottle() if you prefer
+ app = bottle.default_app() # or bottle.Bottle() if you prefer
- app.conf['autojson'] = False # Turns off the "autojson" feature
- app.conf['sqlite.db'] = ':memory:' # Tells the sqlite plugin which db to use
- app.conf['myapp.param'] = 'value' # Example for a custom config value.
+ app.config['autojson'] = False # Turns off the "autojson" feature
+ app.config['sqlite.db'] = ':memory:' # Tells the sqlite plugin which db to use
+ app.config['myapp.param'] = 'value' # Example for a custom config value.
# Change many values at once
- app.conf.update({
+ app.config.update({
'autojson': False,
'sqlite.db': ':memory:',
'myapp.param': 'value'
})
# Add default values
- app.conf.setdefault('myapp.param2', 'some default')
+ app.config.setdefault('myapp.param2', 'some default')
# Receive values
- param = app.conf['myapp.param']
- param2 = app.conf.get('myapp.param2', 'fallback value')
+ param = app.config['myapp.param']
+ param2 = app.config.get('myapp.param2', 'fallback value')
# An example route using configuration values
@app.route('/about', view='about.rst')
def about():
- email = app.conf.get('my.email', 'nomail@example.com')
+ email = app.config.get('my.email', 'nomail@example.com')
return {'email': email}
The app object is not always available, but as long as you are within a request context, you can use the `request` object to get the current application and its configuration::
from bottle import request
def is_admin(user):
- return user == request.app.conf['myapp.admin_user']
+ return user == request.app.config['myapp.admin_user']
Naming Convention
=================
@@ -53,42 +53,64 @@ Naming Convention
To make life easier, plugins and applications should follow some simple rules when it comes to config parameter names:
- All keys should be lowercase strings and follow the rules for python identifiers (no special characters but the underscore).
-- Namespaces are separated by dots (e.g. ``namespace.field`` or ``namespace.subnamespace.field``.
+- Namespaces are separated by dots (e.g. ``namespace.field`` or ``namespace.subnamespace.field``).
- Bottle uses the root namespace for its own configuration. Plugins should store all their variables in their own namespace (e.g. ``sqlite.db`` or ``werkzeug.use_debugger``).
- Your own application should use a separate namespace (e.g. ``myapp.*``).
Loading Configuration from a File
-==================================
+=================================
+
+.. versionadded 0.12
-There is currently no built-in way to read configuration from a file, but it is quite easy to build your own configuration loader. Python provides a parser for the ``*.ini`` file format in its standard library. The config file looks like this:
+Configuration files are useful if you want to enable non-programmers to configure your application,
+or just don't want to hack python module files just to change the database port. A very common syntax for configuration files is shown here:
.. code-block:: ini
[sqlite]
db = /tmp/test.db
commit = auto
-
+
[myapp]
admin_user = defnull
-And the code to read such a file can be seen here::
+With :meth:`ConfigDict.load_config` you can load these ``*.ini`` style configuration
+files from disk and import their values into your existing configuration::
- from configparser import SaveConfigParser
- def load_config(app, inifile):
- ini = SaveConfigParser()
- ini.read(inifile)
- for section in ini.sections():
- app.conf.update(section, ini.items(section))
+ app.config.load_config('/etc/myapp.conf')
+
+Loading Configuration from a nested :class:`dict`
+=================================================
+
+.. versionadded 0.12
+
+Another useful method is :meth:`ConfigDict.load_dict`. This method takes
+an entire structure of nested dictionaries and turns it into a flat list of keys and values with namespaced keys::
+
+ # Load an entire dict structure
+ app.config.load_dict({
+ 'autojson': False,
+ 'sqlite': { 'db': ':memory:' },
+ 'myapp': {
+ 'param': 'value',
+ 'param2': 'value2'
+ }
+ })
+
+ assert app.config['myapp.param'] == 'value'
+
+ # Load configuration from a json file
+ with open('/etc/myapp.json') as fp:
+ app.config.load_dict(json.load(fp))
-This example uses a little trick: If the first parameter of the :meth:`ConfDict.update` method is a string, all keys are stored in that namespace.
Listening to configuration changes
==================================
.. versionadded 0.12
-The ``config`` hook on the application object is triggered each time a value in :attr:`Bottle.conf` is changed. This hook can be used to react on configuration changes at runtime, for example reconnect to a new database, change the debug settings on a background service or resize worker thread pools. The hook callback receives two arguments (key, new_value) and is called before the value is actually changed in the dictionary. Raising an exception from a hook callback cancels the change and the old value is preserved.
+The ``config`` hook on the application object is triggered each time a value in :attr:`Bottle.config` is changed. This hook can be used to react on configuration changes at runtime, for example reconnect to a new database, change the debug settings on a background service or resize worker thread pools. The hook callback receives two arguments (key, new_value) and is called before the value is actually changed in the dictionary. Raising an exception from a hook callback cancels the change and the old value is preserved.
::
@@ -99,12 +121,15 @@ The ``config`` hook on the application object is triggered each time a value in
The hook callbacks cannot *change* the value that is to be stored to the dictionary. That is what filters are for.
+
.. conf-meta:
Filters and other Meta Data
===========================
-:class:`ConfDict` allows you to store meta data along with configuration keys. Two meta fields are currently defined:
+.. versionadded 0.12
+
+:class:`ConfigDict` allows you to store meta data along with configuration keys. Two meta fields are currently defined:
help
A help or description string. May be used by debugging, introspection or
@@ -130,12 +155,14 @@ This feature is most useful for plugins. They can validate their config paramete
app = bottle.default_app()
app.install(SomePlugin())
- app.conf['some.list'] = 'a;b;c' # Actually stores ['a', 'b', 'c']
- app.conf['some.int'] = 'not an int' # raises ValueError
+ app.config['some.list'] = 'a;b;c' # Actually stores ['a', 'b', 'c']
+ app.config['some.int'] = 'not an int' # raises ValueError
API Documentation
=================
-.. autoclass:: ConfDict
+.. versionadded 0.12
+
+.. autoclass:: ConfigDict
:members: