Spec-Zone.ru › Flask 1.0

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

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

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

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

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

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

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

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

app.testing = True

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

app.config.update(
    TESTING=True,
    SECRET_KEY=b'_5#y2L"F4Q8z\n\xec]/'
)

Среда и функции отладки

Значения конфигурации ENV и DEBUG являются особыми, потому что они могут вести себя непредсказуемо, если их изменить после того, как приложение начало настраиваться. Для надёжной установки среды и режима отладки Flask использует переменные окружения.

Среда используется для указания Flask, расширениям и другим программам, таким как Sentry, в какой среде выполняется Flask. Она управляется переменной окружения FLASK_ENV и по умолчанию равна production.

Установка FLASK_ENV в development включит режим отладки. flask run будет использовать интерактивный отладчик и перезагрузчик по умолчанию в режиме отладки. Чтобы управлять этим отдельно от среды, используйте флаг FLASK_DEBUG.

Изменено в версии 1.0: Добавлен FLASK_ENV для управления средой отдельно от режима отладки. Среда разработки включает режим отладки.

Для переключения Flask на среду разработки и включения режима отладки установите FLASK_ENV.

$ export FLASK_ENV=development
$ flask run

(В Windows используйте set вместо export.)

Рекомендуется использовать переменные окружения, как описано выше. Хотя можно установить ENV и DEBUG в вашей конфигурации или коде, это категорически не рекомендуется. Их нельзя прочитать командой flask на ранней стадии, и некоторые системы или расширения, возможно, уже сконфигурировались на основе предыдущего значения.

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

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

ENV

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

Не включайте режим разработки при развертывании в продакшене.

Значение по умолчанию: 'production'

Введено в версии 1.0.

DEBUG

Включён ли режим отладки. При использовании flask run для запуска сервера разработки, будет показан интерактивный отладчик для необработанных исключений, а сервер будет перезагружаться при изменении кода. Атрибут debug сопоставляется с этим ключом конфигурации. Он включён, когда ENV равен 'development', и переопределяется переменной окружения FLASK_DEBUG. Он может вести себя непредсказуемо, если установлен в коде.

Не включайте режим отладки при развертывании в продакшене.

Значение по умолчанию: True если ENV равно 'development', или False в противном случае.

TESTING

Включить тестовый режим. Исключение распространяются вместо обработки обработчиками ошибок приложения. Расширения также могут изменить своё поведение для облегчения тестирования. Вы должны включать это в своих тестах.

Значение по умолчанию: False

PROPAGATE_EXCEPTIONS

Исключения повторно генерируются, а не обрабатываются обработчиками ошибок приложения. Если не установлено, это неявно верно, если TESTING или DEBUG включены.

Значение по умолчанию: None

PRESERVE_CONTEXT_ON_EXCEPTION

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

Значение по умолчанию: None

TRAP_HTTP_EXCEPTIONS

Если нет обработчика для исключения типа HTTPException, повторно генерируется для обработки интерактивным отладчиком, вместо возврата как простого ответа об ошибке.

Значение по умолчанию: False

TRAP_BAD_REQUEST_ERRORS

Попытка получить доступ к ключу, которого нет в словарях запросов, таких как args и form, вернёт страницу ошибки 400 Bad Request. Включите, чтобы рассматривать ошибку как необработанное исключение, чтобы вы получили интерактивный отладчик. Это более специфическая версия TRAP_HTTP_EXCEPTIONS . Если не установлено, то включено в режиме отладки.

Значение по умолчанию: None

SECRET_KEY

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

python -c 'import os; print(os.urandom(16))'
b'_5#y2L"F4Q8z\n\xec]/'

Не раскрывайте секретный ключ при публикации вопросов или коммитах кода.

Значение по умолчанию: None

SESSION_COOKIE_NAME

Имя куки сессии. Можно изменить, если у вас уже есть куки с таким же именем.

Значение по умолчанию: 'session'

SESSION_COOKIE_DOMAIN

Правило соответствия домену, для которого куки сессии будет действителен. Если не задан, куки будет действовать для всех поддоменов SERVER_NAME. Если False, домен куки не будет установлен.

Значение по умолчанию: None

SESSION_COOKIE_PATH

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

Значение по умолчанию: None

SESSION_COOKIE_HTTPONLY

Браузеры не позволят JavaScript получить доступ к кукам, помеченным как «только HTTP», для обеспечения безопасности.

Значение по умолчанию: True

SESSION_COOKIE_SECURE

Браузеры будут отправлять куки только с запросами по HTTPS, если куки помечены как «безопасные». Приложение должно быть доступно по HTTPS, чтобы это имело смысл.

Значение по умолчанию: False

SESSION_COOKIE_SAMESITE

Ограничить, как куки отправляются с запросами с внешних сайтов. Может быть установлен на 'Lax' (рекомендуется) или 'Strict'. См. Параметры Set-Cookie.

Значение по умолчанию: None

Введено в версии 1.0.

PERMANENT_SESSION_LIFETIME

Если session.permanent истина, срок действия куки будет установлен на это количество секунд в будущем. Может быть как datetime.timedelta, так и int.

Реализация куки Flask проверяет, что криптографическая подпись не старше этого значения.

Значение по умолчанию: timedelta(days=31) (2678400 секунд)

SESSION_REFRESH_EACH_REQUEST

Управление отправкой куки с каждым ответом, когда session.permanent истина. Отправка куки каждый раз (значение по умолчанию) более надёжно предотвращает истечение сессии, но использует больше пропускной способности. На непостоянные сессии это не влияет.

Значение по умолчанию: True

USE_X_SENDFILE

При обслуживании файлов установите заголовок X-Sendfile вместо отправки данных с помощью Flask. Некоторые веб-серверы, такие как Apache, распознают это и отправляют данные более эффективно. Это имеет смысл только при использовании такого сервера.

Значение по умолчанию: False

SEND_FILE_MAX_AGE_DEFAULT

При обслуживании файлов установите максимальный срок хранения кэша на это количество секунд. Может быть значением типа datetime.timedelta или int. Переопределите это значение на уровне каждого файла, используя get_send_file_max_age() в приложении или модуле.

По умолчанию: timedelta(hours=12) (43200 секунд)

SERVER_NAME

Укажите приложению хост и порт, к которому оно привязано. Необходим для поддержки соответствия маршрутов поддоменам.

Если задано, будет использоваться для домена cookie сессии, если SESSION_COOKIE_DOMAIN не задан. Современные веб-браузеры не позволят устанавливать cookie для доменов без точки. Чтобы использовать домен локально, добавьте все имена, которые должны перенаправляться в приложение, в ваш файл hosts.

127.0.0.1 localhost.dev

Если задано, url_for может генерировать внешние URL-адреса только с контекстом приложения, а не с контекстом запроса.

По умолчанию: None

APPLICATION_ROOT

Укажите приложению путь, под которым оно смонтировано приложением/веб-сервером.

Будет использоваться для пути cookie сессии, если SESSION_COOKIE_PATH не задан.

По умолчанию: '/'

PREFERRED_URL_SCHEME

Используйте эту схему для генерации внешних URL-адресов, когда вы не находитесь в контексте запроса.

По умолчанию: 'http'

MAX_CONTENT_LENGTH

Не читайте более этого количества байтов из данных входящего запроса. Если не задано и запрос не указывает CONTENT_LENGTH, никакие данные не будут считаны для обеспечения безопасности.

По умолчанию: None

JSON_AS_ASCII

Сериализуйте объекты в JSON с кодировкой ASCII. Если это отключено, JSON будет возвращён как строка Unicode или закодирован как UTF-8 в jsonify. Это имеет последствия для безопасности при отображении JSON в JavaScript в шаблонах и, как правило, должно оставаться включённым.

По умолчанию: True

JSON_SORT_KEYS

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

По умолчанию: True

JSONIFY_PRETTYPRINT_REGULAR

jsonify ответы будут выводиться с новыми строками, пробелами и отступами для удобства чтения человеком. Всегда включено в режиме отладки.

По умолчанию: False

JSONIFY_MIMETYPE

MIME-тип jsonify ответов.

По умолчанию: 'application/json'

TEMPLATES_AUTO_RELOAD

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

По умолчанию: None

EXPLAIN_TEMPLATE_LOADING

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

По умолчанию: False

MAX_COOKIE_SIZE

Выводить предупреждение, если заголовки cookie превышают это количество байтов. По умолчанию 4093. Более крупные cookie могут быть проигнорированы браузерами. Установите значение в 0 для отключения предупреждения.

Изменено в версии 1.0: LOGGER_NAME и LOGGER_HANDLER_POLICY были удалены. Обратитесь к Регистрация для получения информации о настройке.

Добавлен ENV для отражения переменной окружения FLASK_ENV.

Добавлен SESSION_COOKIE_SAMESITE для управления параметром SameSite cookie сессии.

Добавлен MAX_COOKIE_SIZE для управления предупреждением от Werkzeug.

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

Новое в версии 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-файлы. В объекте config хранятся только значения с заглавными буквами. Поэтому убедитесь, что используете заглавные буквы для ваших ключей конфигурации.

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

# Example configuration
DEBUG = False
SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'

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

Настройка из переменных окружения

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

Переменные окружения можно установить в Linux или OS X с помощью команды export в оболочке перед запуском сервера:

$ export SECRET_KEY='5f352379324c22463451387a0aec5d2f'
$ export MAIL_ENABLED=false
$ python run-app.py
 * Running on http://127.0.0.1:5000/

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

>set SECRET_KEY='5f352379324c22463451387a0aec5d2f'

Хотя этот подход прост в использовании, важно помнить, что переменные окружения — это строки; они не десериализуются в типы Python автоматически.

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

import os

_mail_enabled = os.environ.get("MAIL_ENABLED", default="true")
MAIL_ENABLED = _mail_enabled.lower() in {"1", "t", "true"}

SECRET_KEY = os.environ.get("SECRET_KEY")

if not SECRET_KEY:
    raise ValueError("No SECRET_KEY set for Flask application")

Обратите внимание, что любое значение, кроме пустой строки, будет интерпретировано как логическое True значение в Python, что требует осторожности, если среда явно задаёт значения, предназначенные для False.

Убедитесь, что конфигурацию загружаете очень рано, чтобы расширения могли получить доступ к конфигурации при запуске. В объекте config также есть другие методы загрузки из отдельных файлов. Для полной справки ознакомьтесь с документацией класса 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')

Обратите внимание, что from_object() не создаёт экземпляр класса. Если вам нужно создать экземпляр класса, например, для доступа к свойству, сделайте это до вызова from_object():

from configmodule import ProductionConfig
app.config.from_object(ProductionConfig())

# Alternatively, import via string:
from werkzeug.utils import import_string
cfg = import_string('configmodule.ProductionConfig')()
app.config.from_object(cfg)

Создание объекта конфигурации позволяет использовать @property в ваших конфигурационных классах:

class Config(object):
    """Base config, uses staging database server."""
    DEBUG = False
    TESTING = False
    DB_SERVER = '192.168.1.56'

    @property
    def DATABASE_URI(self):         # Note: all caps
        return 'mysql://user@{}/foo'.format(self.DB_SERVER)

class ProductionConfig(Config):
    """Uses production database server."""
    DB_SERVER = '192.168.19.32'

class DevelopmentConfig(Config):
    DB_SERVER = 'localhost'
    DEBUG = True

class TestingConfig(Config):
    DB_SERVER = 'localhost'
    DEBUG = True
    DATABASE_URI = 'sqlite:///:memory:'

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

  • Сохраняйте файл конфигурации по умолчанию в системе контроля версий. Либо заполните конфигурацию этим значением по умолчанию, либо импортируйте его в свои файлы конфигурации, прежде чем переопределить значения.
  • Используйте переменную окружения для переключения между конфигурациями. Это можно сделать вне интерпретатора 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 для предварительной загрузки конфигурации из модуля, а затем переопределить конфигурацию из файла в папке экземпляра, если он существует:

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/1.0.x/config/

Spec-Zone.ru

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