Spec-Zone.ru › Flask 2.2

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

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

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

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

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

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

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

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

app.testing = True

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

app.config.update(
    TESTING=True,
    SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
)

Режим отладки

Значение конфигурации DEBUG является специальным, потому что оно может вести себя непредсказуемо, если его изменить после того, как приложение начало настраиваться. Чтобы надёжно установить режим отладки, используйте опцию --debug в команде flask. ``flask run`` по умолчанию будет использовать интерактивный отладчик и перезагрузчик в режиме отладки.

$ flask --app hello --debug run

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

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

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

ENV

В какой среде приложение запущено. Атрибут env сопоставлен с этим ключом конфигурации.

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

Устарело начиная с версии 2.2: Будет удалено в Flask 2.3. Используйте --debug вместо этого.

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

Добавлена в версии 1.0.

DEBUG

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

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

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

TESTING

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

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

PROPAGATE_EXCEPTIONS

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

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

TRAP_HTTP_EXCEPTIONS

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

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

TRAP_BAD_REQUEST_ERRORS

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

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

SECRET_KEY

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

$ python -c 'import secrets; print(secrets.token_hex())'
'192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'

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

По умолчанию: 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 равно true, срок действия куки будет установлен на это число секунд в будущем. Может быть либо datetime.timedelta, либо int.

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

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

SESSION_REFRESH_EACH_REQUEST

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

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

USE_X_SENDFILE

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

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

SEND_FILE_MAX_AGE_DEFAULT

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

Если None, send_file указывает браузеру использовать условные запросы вместо кэширования по таймеру, что обычно предпочтительнее.

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

SERVER_NAME

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

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

127.0.0.1 localhost.dev

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

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

APPLICATION_ROOT

Укажите приложению, под какой путь оно смонтировано приложением/веб-сервером. Это используется для генерации URL-адресов вне контекста запроса (внутри запроса, диспетчер отвечает за установку SCRIPT_NAME вместо этого; см. Диспечеризация приложений для примеров конфигурации диспетчеризации).

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

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

PREFERRED_URL_SCHEME

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

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

MAX_CONTENT_LENGTH

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

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

JSON_AS_ASCII

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

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

Устарело начиная с версии 2.2: Будет удалено в Flask 2.3. Задайте app.json.ensure_ascii вместо этого.

JSON_SORT_KEYS

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

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

Устарело начиная с версии 2.2: Будет удалено в Flask 2.3. Задайте app.json.sort_keys вместо этого.

END_OF_DOCUMENT_MARKER
JSONIFY_PRETTYPRINT_REGULAR

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

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

Устаревшее начиная с версии 2.2: Будет удалено в Flask 2.3. Установите app.json.compact вместо этого.

JSONIFY_MIMETYPE

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

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

Устаревшее начиная с версии 2.2: Будет удалено в Flask 2.3. Установите app.json.mimetype вместо этого.

TEMPLATES_AUTO_RELOAD

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

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

EXPLAIN_TEMPLATE_LOADING

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

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

MAX_COOKIE_SIZE

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

Изменено в версии 2.2: Убрано PRESERVE_CONTEXT_ON_EXCEPTION.

Изменено в версии 2.2: JSON_AS_ASCII, JSON_SORT_KEYS, JSONIFY_MIMETYPE, и JSONIFY_PRETTYPRINT_REGULAR будут удалены в Flask 2.3. У поставщика по умолчанию app.json есть эквивалентные атрибуты.

Изменено в версии 2.2: ENV будет удалено в Flask 2.3. Используйте --debug вместо этого.

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

Изменено в версии 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

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

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

Общий шаблон такой:

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

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

$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
$ flask run
 * Running on http://127.0.0.1:5000/
$ set -x YOURAPPLICATION_SETTINGS /path/to/settings.cfg
$ flask run
 * Running on http://127.0.0.1:5000/
> set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
> flask run
 * Running on http://127.0.0.1:5000/
> $env:YOURAPPLICATION_SETTINGS = "\path\to\settings.cfg"
> flask run
 * Running on http://127.0.0.1:5000/

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

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

# Example configuration
SECRET_KEY = '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'

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

Настройка из файлов данных

Также можно загрузить конфигурацию из файла в формате по вашему выбору, используя from_file(). Например, для загрузки из файла TOML:

import toml
app.config.from_file("config.toml", load=toml.load)

Или из файла JSON:

import json
app.config.from_file("config.json", load=json.load)
END_OF_DOCUMENT_MARKER

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

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

Переменные среды можно задать в оболочке перед запуском сервера:

$ export FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
$ export FLASK_MAIL_ENABLED=false
$ flask run
 * Running on http://127.0.0.1:5000/
$ set -x FLASK_SECRET_KEY "5f352379324c22463451387a0aec5d2f"
$ set -x FLASK_MAIL_ENABLED false
$ flask run
 * Running on http://127.0.0.1:5000/
> set FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
> set FLASK_MAIL_ENABLED=false
> flask run
 * Running on http://127.0.0.1:5000/
> $env:FLASK_SECRET_KEY = "5f352379324c22463451387a0aec5d2f"
> $env:FLASK_MAIL_ENABLED = "false"
> flask run
 * Running on http://127.0.0.1:5000/

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

app.config.from_prefixed_env()
app.config["SECRET_KEY"]  # Is "5f352379324c22463451387a0aec5d2f"

Префикс по умолчанию FLASK_. Это настраивается через аргумент prefix метода from_prefixed_env().

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

При добавлении булевого значения с помощью анализа JSON по умолчанию только «true» и «false», в нижнем регистре, являются допустимыми значениями. Имейте в виду, что любая непустая строка считается True в Python.

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

$ export FLASK_MYAPI__credentials__username=user123
app.config["MYAPI"]["credentials"]["username"]  # Is "user123"

В Windows ключи переменных среды всегда записываются заглавными буквами, поэтому вышеприведенный пример приведет к MYAPI__CREDENTIALS__USERNAME.

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

Рекомендации по лучшим практикам конфигурации

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

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

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

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

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):
    TESTING = False

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

class DevelopmentConfig(Config):
    DATABASE_URI = "sqlite:////tmp/foo.db"

class TestingConfig(Config):
    DATABASE_URI = 'sqlite:///:memory:'
    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."""
    TESTING = False
    DB_SERVER = '192.168.1.56'

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

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

class DevelopmentConfig(Config):
    DB_SERVER = 'localhost'

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

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

  • Храните стандартную конфигурацию в системе контроля версий. Либо заполните конфигурацию этой стандартной конфигурацией, либо импортируйте её в собственные файлы конфигурации перед переопределением значений.
  • Используйте переменную среды для переключения между конфигурациями. Это можно сделать вне интерпретатора Python и значительно упростит разработку и развертывание, так как вы сможете быстро и легко переключаться между разными конфигурациями, не изменяя код. Если вы работаете часто над разными проектами, вы можете даже создать собственную скрипт для подготовки, который активирует виртуальную среду и экспортирует для вас конфигурацию разработки.
  • Используйте инструмент, такой как 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/pythonX.Y/site-packages/myapp
    $PREFIX/var/myapp-instance
    

    $PREFIX — префикс вашей установки Python. Это может быть /usr или путь к вашей виртуальной среде. Вы можете вывести значение 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–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.2.x/config/

Spec-Zone.ru

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