Обработка конфигурации
Журнал изменений
Новая версия 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 внутри:
| включение/выключение режима отладки |
| включение/выключение тестового режима |
| явное включение или выключение распространения исключений. Если не установлено или явно установлено в |
| По умолчанию, если приложение находится в режиме отладки, контекст запроса не удаляется при возникновении исключений, чтобы отладчики могли инспектировать данные. Это можно отключить с помощью этого ключа. Вы также можете использовать эту настройку для принудительного включения в неотладочном выполнении, что может быть полезно для отладки приложений в производстве (но также очень рискованно). |
| секретный ключ |
| имя куки сессии |
| домен для куки сессии. Если это не задано, куки будет действителен для всех поддоменов |
| путь для куки сессии. Если это не задано, куки будет действителен для всего |
| управляет тем, должна ли куки устанавливаться с флагом httponly. По умолчанию |
| управляет тем, должна ли куки устанавливаться с флагом secure. По умолчанию |
| время жизни постоянной сессии как объект |
| Этот флаг управляет тем, как обновляются постоянные сессии. Если установлено |
| включение/выключение x-sendfile |
| имя логгера |
| политика обработчика логов по умолчанию. По умолчанию |
| имя и номер порта сервера. Требуется для поддержки поддоменов (например: |
| Если приложение не занимает весь домен или поддомен, это можно установить в путь, где настроено приложение. Это для значения пути куки сессии. Если используются домены, это должно быть |
| Если установлено значение в байтах, Flask отклонит входящие запросы с длиной содержимого, превышающей это значение, вернув код состояния 413. |
| Максимальный срок хранения по умолчанию для управления кешированием, используемый с |
| Если установлено в |
| Внутренние структуры данных Werkzeug, связанные с данными конкретного запроса, будут генерировать особые ошибки ключей, которые также являются ошибками неправильного запроса. Аналогичным образом, многие операции могут неявно завершиться ошибкой BadRequest для согласованности. Поскольку при отладке полезно знать, почему именно произошла ошибка, этот флаг можно использовать для отладки таких ситуаций. Если эта конфигурация установлена в |
| Схема URL, которая должна использоваться для генерации URL, если схема URL недоступна. По умолчанию |
| По умолчанию Flask сериализует объект в JSON с кодировкой ASCII. Если установлено в |
| По умолчанию Flask сериализует JSON-объекты таким образом, что ключи упорядочены. Это делается для того, чтобы независимо от зерна хеширования словаря значение возврата было согласованным, чтобы не повредить внешние кэши HTTP. Вы можете изменить поведение по умолчанию, изменив эту переменную. Это не рекомендуется, но может повысить производительность за счет кешируемости. |
| Если установлено в |
| MIME-тип, используемый для ответов jsonify. |
| Нужно ли проверять изменения исходного текста шаблона и автоматически перегружать его. По умолчанию значение |
| Если это включено, каждая попытка загрузки шаблона запишет сообщение информации в логгер, описывающее попытки поиска шаблона. Это может быть полезно для выяснения причин, по которым шаблоны не найдены или загружаются неправильные шаблоны. |
Подробнее о SERVER_NAME
Ключ SERVER_NAME используется для поддержки поддоменов. Так как Flask не может определить часть поддомена без знания фактического имени сервера, это необходимо, если вы хотите работать с поддоменами. Это также используется для куки сессии.
Пожалуйста, имейте в виду, что не только Flask имеет проблему с неизвестностью поддоменов, это также касается вашего веб-браузера. Большинство современных веб-браузеров не позволят устанавливать куки между поддоменами на имя сервера без точек в нем. Таким образом, если имя вашего сервера 'localhost', вы не сможете установить куки для 'localhost' и любого поддомена. В таком случае выберите другое имя сервера, например, 'myapplication.local', и добавьте это имя + поддомены, которые вы хотите использовать, в вашу конфигурацию хоста или настройте локальный bind.
Журнал изменений
Новое в версии 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% решения для этой проблемы, но есть несколько моментов, которые вы можете иметь в виду, чтобы улучшить этот опыт:
- Создайте своё приложение в функции и регистрируйте шаблоны на нём. Таким образом, вы можете создавать несколько экземпляров приложения с прикреплёнными различными конфигурациями, что значительно облегчает тестирование. Вы можете использовать это, чтобы передавать конфигурацию по мере необходимости.
- Не пишите код, которому нужна конфигурация во время импорта. Если вы ограничите себя до доступа к конфигурации только при запросах, вы можете переконфигурировать объект по мере необходимости.
Разработка / Производство
Большинству приложений требуется более одной конфигурации. Должны быть отдельные конфигурации для сервера в режиме производства и для сервера, используемого во время разработки. Наиболее простой способ сделать это — использовать стандартную конфигурацию, которая всегда загружается и является частью контроля версий, и отдельную конфигурацию, которая переопределяет значения по необходимости, как показано в примере выше:
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/