Spec-Zone.ru › Bottle 0.12

Настройка (ЭСКИЗ)

Приложения Bottle могут хранить свою конфигурацию в Bottle.config, объекте, подобном словарю, и центральном месте для приложений. Этот словарь управляет многими аспектами фреймворка, сообщает (более новым) плагинам, что делать, и может использоваться для хранения собственной конфигурации.

Основы конфигурации

Объект Bottle.config ведет себя очень похоже на обычный словарь. Все стандартные методы словаря работают как ожидается. Давайте начнем с некоторых примеров:

import bottle
app = bottle.default_app()             # or bottle.Bottle() if you prefer

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.config.update({
    'autojson': False,
    'sqlite.db': ':memory:',
    'myapp.param': 'value'
})

# Add default values
app.config.setdefault('myapp.param2', 'some default')

# Receive values
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.config.get('my.email', 'nomail@example.com')
    return {'email': email}

Объект приложения не всегда доступен, но пока вы находитесь в контексте запроса, вы можете использовать объект request для получения текущего приложения и его конфигурации:

from bottle import request
def is_admin(user):
    return user == request.app.config['myapp.admin_user']

Конвенция именования

Для упрощения жизни, плагины и приложения должны придерживаться некоторых простых правил при именовании параметров конфигурации:

  • Все ключи должны быть строками в нижнем регистре и следовать правилам идентификаторов Python (без специальных символов, кроме подчеркивания).
  • Пространства имен разделяются точками (например, namespace.field или namespace.subnamespace.field).
  • Bottle использует корневое пространство имен для собственной конфигурации. Плагины должны хранить все свои переменные в собственном пространстве имен (например, sqlite.db или werkzeug.use_debugger).
  • Ваше собственное приложение должно использовать отдельное пространство имен (например, myapp.*).

Загрузка конфигурации из файла

Файлы конфигурации полезны, если вы хотите позволить не программистам настраивать ваше приложение, или просто не хотите вносить изменения в файлы Python-модулей, чтобы изменить порт базы данных. Очень распространенный синтаксис для файлов конфигурации показан здесь:

[bottle]
debug = True

[sqlite]
db = /tmp/test.db
commit = auto

[myapp]
admin_user = defnull

С помощью ConfigDict.load_config() вы можете загрузить эти файлы конфигурации в стиле *.ini с диска и импортировать их значения в существующую конфигурацию:

app.config.load_config('/etc/myapp.conf')

Загрузка конфигурации из вложенного словаря

Другой полезный метод — ConfigDict.load_dict(). Этот метод принимает всю структуру вложенных словарей и преобразует ее в плоский список ключей и значений с именованными ключами:

# 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))

Прослушивание изменений конфигурации

Обработчик config в объекте приложения срабатывает каждый раз, когда значение в Bottle.config изменяется. Этот обработчик можно использовать для реагирования на изменения конфигурации во время выполнения, например, для повторного подключения к новой базе данных, изменения настроек отладки фонового сервиса или изменения пулов потоков-рабочих. Обработчик-обратный вызов получает два аргумента (ключ, новое_значение) и вызывается перед тем, как значение фактически изменится в словаре. Выброс исключения из обработчика-обратного вызова отменяет изменение, и старое значение сохраняется.

@app.hook('config')
def on_config_change(key, value):
  if key == 'debug':
      switch_own_debug_mode_to(value)

Обработчики-обратные вызовы не могут изменить значение, которое должно быть сохранено в словаре. Для этого предназначены фильтры.

Фильтры и другие метаданные

ConfigDict позволяет хранить метаданные вместе с ключами конфигурации. В настоящее время определены два поля метаданных:

help
Строка справки или описания. Может использоваться средствами отладки, интроспекции или администрирования для помощи системному администратору в настройке приложения.
filter
Вызываемый объект, который принимает и возвращает единственное значение. Если для ключа определен фильтр, любое новое значение, сохраненное для этого ключа, сначала передается через обратный вызов фильтра. Фильтр может использоваться для преобразования значения в другой тип, проверки на недействительные значения (выброс ValueError) или вызова побочных эффектов.

Эта функция наиболее полезна для плагинов. Они могут валидировать свои параметры конфигурации или вызывать побочные эффекты с помощью фильтров и документировать свою конфигурацию с помощью полей help:

class SomePlugin(object):
    def setup(app):
        app.config.meta_set('some.int', 'filter', int)
        app.config.meta_set('some.list', 'filter',
            lambda val: str(val).split(';'))
        app.config.meta_set('some.list', 'help',
            'A semicolon separated list.')

    def apply(self, callback, route):
        ...

import bottle
app = bottle.default_app()
app.install(SomePlugin())

app.config['some.list'] = 'a;b;c'     # Actually stores ['a', 'b', 'c']
app.config['some.int'] = 'not an int' # raises ValueError

Документация API

class ConfigDict(*a, **ka) [source]

Хранилище конфигурации, подобное словарю, с дополнительной поддержкой пространств имен, валидаторов, метаданных, слушателей изменений и т. д.

Это хранилище оптимизировано для быстрого доступа к чтению. Получение ключа или использование методов словаря, не изменяющих его (например, dict.get()) не имеет накладных расходов по сравнению с обычным словарем.

load_config(filename) [source]

Загрузка значений из файла конфигурации в формате *.ini.

Если файл конфигурации содержит разделы, их имена используются в качестве пространств имен для значений внутри. Два специальных раздела DEFAULT и bottle относятся к корневому пространству имен (без префикса).

load_dict(source, namespace='', make_namespaces=False) [source]

Импорт значений из структуры словаря. Вложение может быть использовано для представления пространств имен.

>>> ConfigDict().load_dict({'name': {'space': {'key': 'value'}}})
{'name.space.key': 'value'}
update(*a, **ka) [source]

Если первый параметр является строкой, все ключи префиксруются этим пространством имен. В остальном он работает так же, как и обычный dict.update(). Пример: update('some.namespace', key='value')

meta_get(key, metafield, default=None) [source]

Возвращает значение поля метаданных для ключа.

meta_set(key, metafield, value) [source]

Устанавливает поле метаданных для ключа в новое значение. Это запускает обработчик изменений для существующих ключей.

meta_list(key) [source]

Возвращает итерируемый объект имен полей метаданных, определенных для ключа.

© 2009–2017 Marcel Hellkamp
Licensed under the MIT License.
https://bottlepy.org/docs/0.12/configuration.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API