Spec-Zone.ru › Flask 0.12

Обработка конфигурации

Журнал изменений

Новая версия 0.3.

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

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

Независимо от того, как вы загружаете свою конфигурацию, доступен объект config, который содержит загруженные значения конфигурации: атрибут config объекта Flask. Именно сюда Flask помещает определенные значения конфигурации, а также расширения могут помещать свои значения конфигурации. Но здесь также вы можете хранить собственную конфигурацию.

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

Атрибут config фактически является подклассом словаря и может быть изменен так же, как любой словарь:

app = Flask(__name__)
app.config['DEBUG'] = True

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

app.debug = True

Чтобы обновить несколько ключей одновременно, можно использовать метод dict.update():

app.config.update(
    DEBUG=True,
    SECRET_KEY='...'
)

Встроенные значения конфигурации

Следующие значения конфигурации используются во Flask внутри:

DEBUG

включение/выключение режима отладки

TESTING

включение/выключение тестового режима

PROPAGATE_EXCEPTIONS

явное включение или выключение распространения исключений. Если не установлено или явно установлено в None, это неявно истинно, если либо TESTING, либо DEBUG истинно.

PRESERVE_CONTEXT_ON_EXCEPTION

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

SECRET_KEY

секретный ключ

SESSION_COOKIE_NAME

имя куки сессии

SESSION_COOKIE_DOMAIN

домен для куки сессии. Если это не задано, куки будет действителен для всех поддоменов SERVER_NAME.

SESSION_COOKIE_PATH

путь для куки сессии. Если это не задано, куки будет действителен для всего APPLICATION_ROOT или, если это не задано, для '/'.

SESSION_COOKIE_HTTPONLY

управляет тем, должна ли куки устанавливаться с флагом httponly. По умолчанию True.

SESSION_COOKIE_SECURE

управляет тем, должна ли куки устанавливаться с флагом secure. По умолчанию False.

PERMANENT_SESSION_LIFETIME

время жизни постоянной сессии как объект datetime.timedelta. Начиная с Flask 0.8, это также может быть целое число, представляющее секунды.

SESSION_REFRESH_EACH_REQUEST

Этот флаг управляет тем, как обновляются постоянные сессии. Если установлено True (что является значением по умолчанию), то куки обновляется при каждом запросе, что автоматически увеличивает срок действия. Если установлено False, заголовок set-cookie отправляется только при изменении сессии. На непостоянные сессии это не влияет.

USE_X_SENDFILE

включение/выключение x-sendfile

LOGGER_NAME

имя логгера

LOGGER_HANDLER_POLICY

политика обработчика логов по умолчанию. По умолчанию 'always', что означает, что обработчик логов по умолчанию всегда активен. 'debug' активирует логирование только в режиме отладки, 'production' — только в режиме производства, а 'never' — полностью отключает его.

SERVER_NAME

имя и номер порта сервера. Требуется для поддержки поддоменов (например: 'myapp.dev:5000'). Обратите внимание, что localhost не поддерживает поддомены, поэтому установка его в «localhost» не поможет. Установка SERVER_NAME также по умолчанию включает генерацию URL без контекста запроса, но с контекстом приложения.

APPLICATION_ROOT

Если приложение не занимает весь домен или поддомен, это можно установить в путь, где настроено приложение. Это для значения пути куки сессии. Если используются домены, это должно быть None.

MAX_CONTENT_LENGTH

Если установлено значение в байтах, Flask отклонит входящие запросы с длиной содержимого, превышающей это значение, вернув код состояния 413.

SEND_FILE_MAX_AGE_DEFAULT

Максимальный срок хранения по умолчанию для управления кешированием, используемый с send_static_file() (обработчик статических файлов по умолчанию) и send_file(), как datetime.timedelta или как количество секунд. Переопределите это значение на основе файла с помощью хука get_send_file_max_age() в Flask или Blueprint соответственно. По умолчанию 43200 (12 часов).

TRAP_HTTP_EXCEPTIONS

Если установлено в True, Flask не будет выполнять обработчики ошибок исключений HTTP, а вместо этого обработает исключение как любое другое и передаст его через стек исключений. Это полезно для сложных ситуаций отладки, когда вам нужно выяснить, откуда исходит исключение HTTP.

TRAP_BAD_REQUEST_ERRORS

Внутренние структуры данных Werkzeug, связанные с данными конкретного запроса, будут генерировать особые ошибки ключей, которые также являются ошибками неправильного запроса. Аналогичным образом, многие операции могут неявно завершиться ошибкой BadRequest для согласованности. Поскольку при отладке полезно знать, почему именно произошла ошибка, этот флаг можно использовать для отладки таких ситуаций. Если эта конфигурация установлена в True, вместо этого вы получите обычный стек отслеживания.

PREFERRED_URL_SCHEME

Схема URL, которая должна использоваться для генерации URL, если схема URL недоступна. По умолчанию http.

JSON_AS_ASCII

По умолчанию Flask сериализует объект в JSON с кодировкой ASCII. Если установлено в False, Flask не будет кодировать в ASCII и выведет строки как есть, вернув строки Unicode. jsonify автоматически закодирует их в utf-8 для передачи, например.

JSON_SORT_KEYS

По умолчанию Flask сериализует JSON-объекты таким образом, что ключи упорядочены. Это делается для того, чтобы независимо от зерна хеширования словаря значение возврата было согласованным, чтобы не повредить внешние кэши HTTP. Вы можете изменить поведение по умолчанию, изменив эту переменную. Это не рекомендуется, но может повысить производительность за счет кешируемости.

JSONIFY_PRETTYPRINT_REGULAR

Если установлено в True (значение по умолчанию), ответы jsonify будут красиво отформатированы, если они не запрошены объектом XMLHttpRequest (управление через заголовок X-Requested-With).

JSONIFY_MIMETYPE

MIME-тип, используемый для ответов jsonify.

TEMPLATES_AUTO_RELOAD

Нужно ли проверять изменения исходного текста шаблона и автоматически перегружать его. По умолчанию значение None, что означает, что Flask проверяет исходный файл только в режиме отладки.

EXPLAIN_TEMPLATE_LOADING

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

Подробнее о SERVER_NAME

Ключ SERVER_NAME используется для поддержки поддоменов. Так как Flask не может определить часть поддомена без знания фактического имени сервера, это необходимо, если вы хотите работать с поддоменами. Это также используется для куки сессии.

Пожалуйста, имейте в виду, что не только Flask имеет проблему с неизвестностью поддоменов, это также касается вашего веб-браузера. Большинство современных веб-браузеров не позволят устанавливать куки между поддоменами на имя сервера без точек в нем. Таким образом, если имя вашего сервера 'localhost', вы не сможете установить куки для 'localhost' и любого поддомена. В таком случае выберите другое имя сервера, например, 'myapplication.local', и добавьте это имя + поддомены, которые вы хотите использовать, в вашу конфигурацию хоста или настройте локальный bind.

END_OF_DOCUMENT_MARKER
Журнал изменений

Новое в версии 0.11: SESSION_REFRESH_EACH_REQUEST, TEMPLATES_AUTO_RELOAD, LOGGER_HANDLER_POLICY, EXPLAIN_TEMPLATE_LOADING

Новое в версии 0.10: JSON_AS_ASCII, JSON_SORT_KEYS, JSONIFY_PRETTYPRINT_REGULAR

Новое в версии 0.9: PREFERRED_URL_SCHEME

Новое в версии 0.8: TRAP_BAD_REQUEST_ERRORS, TRAP_HTTP_EXCEPTIONS, APPLICATION_ROOT, SESSION_COOKIE_DOMAIN, SESSION_COOKIE_PATH, SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SECURE

Новое в версии 0.7: PROPAGATE_EXCEPTIONS, PRESERVE_CONTEXT_ON_EXCEPTION

Новое в версии 0.6: MAX_CONTENT_LENGTH

Новое в версии 0.5: SERVER_NAME

Новое в версии 0.4: LOGGER_NAME

Настройка из файлов

Настройка становится более полезной, если вы можете хранить её в отдельном файле, предпочтительно расположенном вне самого пакета приложения. Это позволяет упаковывать и распространять ваше приложение с помощью различных инструментов управления пакетами (Развёртывание с Setuptools) и, наконец, изменять файл конфигурации после этого.

Поэтому распространённый паттерн такой:

app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')

Сначала загружается конфигурация из модуля yourapplication.default_settings, а затем значения переопределяются содержимым файла, на который указывает переменная среды YOURAPPLICATION_SETTINGS. Эту переменную среды можно установить в Linux или OS X командой export в оболочке перед запуском сервера:

$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
$ python run-app.py
 * Running on http://127.0.0.1:5000/
 * Restarting with reloader...

В системах Windows используйте встроенную команду set:

>set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg

Файлы конфигурации — это фактические Python-файлы. Только значения, записанные в верхнем регистре, фактически сохраняются в объекте конфигурации позднее. Поэтому убедитесь, что для ваших ключей конфигурации используются заглавные буквы.

Вот пример файла конфигурации:

# Example configuration
DEBUG = False
SECRET_KEY = '?\xbf,\xb4\x8d\xa3"<\x9c\xb0@\x0f5\xab,w\xee\x8d$0\x13\x8b83'

Убедитесь, что конфигурация загружается очень рано, чтобы расширения имели возможность получить доступ к конфигурации при запуске. В объекте конфигурации также есть другие методы для загрузки из отдельных файлов. Для полной справки, ознакомьтесь с документацией объекта Config.

Рекомендации по настройке

Недостатком описанного выше подхода является то, что он немного затрудняет тестирование. В общем случае нет единственного 100% решения для этой проблемы, но есть несколько моментов, которые вы можете иметь в виду, чтобы улучшить этот опыт:

  1. Создайте своё приложение в функции и регистрируйте шаблоны на нём. Таким образом, вы можете создавать несколько экземпляров приложения с прикреплёнными различными конфигурациями, что значительно облегчает тестирование. Вы можете использовать это, чтобы передавать конфигурацию по мере необходимости.
  2. Не пишите код, которому нужна конфигурация во время импорта. Если вы ограничите себя до доступа к конфигурации только при запросах, вы можете переконфигурировать объект по мере необходимости.

Разработка / Производство

Большинству приложений требуется более одной конфигурации. Должны быть отдельные конфигурации для сервера в режиме производства и для сервера, используемого во время разработки. Наиболее простой способ сделать это — использовать стандартную конфигурацию, которая всегда загружается и является частью контроля версий, и отдельную конфигурацию, которая переопределяет значения по необходимости, как показано в примере выше:

app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')

Затем вам просто нужно добавить отдельный файл config.py и экспортировать YOURAPPLICATION_SETTINGS=/path/to/config.py, и вы закончили. Однако существуют и альтернативные способы. Например, вы можете использовать импорты или наследование.

В мире Django очень популярно явно указывать импорт в файле конфигурации, добавив from yourapplication.default_settings import * в начало файла, а затем вручную переопределив изменения. Вы также можете проверить переменную среды, например, YOURAPPLICATION_MODE, и установить её значение на production, development и т. д., а затем импортировать разные жёстко запрограммированные файлы, основываясь на этом.

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

class Config(object):
    DEBUG = False
    TESTING = False
    DATABASE_URI = 'sqlite://:memory:'

class ProductionConfig(Config):
    DATABASE_URI = 'mysql://user@localhost/foo'

class DevelopmentConfig(Config):
    DEBUG = True

class TestingConfig(Config):
    TESTING = True

Чтобы включить такую конфигурацию, вам нужно вызвать from_object():

app.config.from_object('configmodule.ProductionConfig')

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

  • Сохраняйте стандартную конфигурацию в системе контроля версий. Либо заполните конфигурацию этой стандартной конфигурацией, либо импортируйте её в свои собственные файлы конфигурации перед переопределением значений.
  • Используйте переменную среды для переключения между конфигурациями. Это можно сделать вне интерпретатора Python и значительно упрощает разработку и развертывание, поскольку вы быстро и легко можете переключаться между различными конфигурациями, не затрагивая код. Если вы часто работаете над разными проектами, вы можете даже создать свою собственную скрипт для получения доступа к этой функции, который активирует virtualenv и экспортирует конфигурацию разработки за вас.
  • Используйте инструмент, такой как fabric, в режиме производства для отдельного внедрения кода и конфигураций на сервер(ы) производства. Подробнее об этом см. в паттерне Развертывание с Fabric.

Папки экземпляров

Журнал изменений

Новое в версии 0.8.

Flask 0.8 вводит папки экземпляров. Flask долгое время позволял ссылаться на пути, относительные к папке приложения (через Flask.root_path). Таким образом, многие разработчики загружали конфигурации, хранящиеся рядом с приложением. К сожалению, это работает хорошо только если приложения не являются пакетами, в этом случае корневой путь относится к содержимому пакета.

В Flask 0.8 был введён новый атрибут: Flask.instance_path. Он относится к новой концепции, называемой «папкой экземпляра». Папка экземпляра предназначена для того, чтобы не находиться под контролем версий и быть специфичной для развертывания. Это идеальное место для размещения элементов, которые либо меняются во время выполнения, либо файлов конфигурации.

Вы можете явно указать путь к папке экземпляра при создании приложения Flask, или вы можете позволить Flask автоматически обнаружить папку экземпляра. Для явного конфигурирования используйте параметр instance_path:

app = Flask(__name__, instance_path='/path/to/instance/folder')

Пожалуйста, имейте в виду, что этот путь должен быть абсолютным при его указании.

Если параметр instance_path не указан, используются следующие значения по умолчанию:

  • Неустановленный модуль:

    /myapp.py
    /instance
    
  • Неустановленный пакет:

    /myapp
        /__init__.py
    /instance
    
  • Установленный модуль или пакет:

    $PREFIX/lib/python2.X/site-packages/myapp
    $PREFIX/var/myapp-instance
    

    $PREFIX — это префикс вашей установки Python. Это может быть /usr или путь к вашему virtualenv. Вы можете напечатать значение sys.prefix, чтобы увидеть, какое значение установлено для префикса.

Поскольку объект конфигурации предоставляет загрузку файлов конфигурации из относительных имён файлов, мы сделали возможным изменение загрузки по именам файлов для относительной ссылки к пути экземпляра, если это нужно. Поведение относительных путей в файлах конфигурации может быть изменено между «относительно корня приложения» (по умолчанию) и «относительно папки экземпляра» с помощью переключателя instance_relative_config в конструктор приложения:

app = Flask(__name__, instance_relative_config=True)

Вот полный пример того, как настроить Flask для предварительной загрузки конфигурации из модуля, а затем переопределения конфигурации из файла в папке config, если она существует:

app = Flask(__name__, instance_relative_config=True)
app.config.from_object('yourapplication.default_settings')
app.config.from_pyfile('application.cfg', silent=True)

Путь к папке экземпляра можно найти в Flask.instance_path. Flask также предоставляет сокращение для открытия файла из папки экземпляра с помощью Flask.open_instance_resource().

Пример использования для обоих:

filename = os.path.join(app.instance_path, 'application.cfg')
with open(filename) as f:
    config = f.read()

# or via open_instance_resource:
with app.open_instance_resource('application.cfg') as f:
    config = f.read()

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/config/

Spec-Zone.ru

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