Spec-Zone.ru › Flask 3.0

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

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

Структура 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 run будет по умолчанию использовать интерактивный отладчик и перезагрузчик в режиме отладки.

$ flask --app hello run --debug

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

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

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

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

Значение параметра Domain в куки сессии. Если не задано, браузеры будут отправлять куки только на точный домен, с которого она была установлена. В противном случае они будут отправлять ее на любые поддомены данного значения.

Не задавать это значение более ограничительно и безопасно, чем задавать.

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

Изменения

Изменено в версии 2.3: Не устанавливается по умолчанию, не возвращается к SERVER_NAME.

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() в приложении или макете.

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

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

SERVER_NAME

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

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

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

Изменения

Изменено в версии 2.3: Не влияет на SESSION_COOKIE_DOMAIN.

APPLICATION_ROOT

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

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

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

PREFERRED_URL_SCHEME

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

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

MAX_CONTENT_LENGTH

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

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

TEMPLATES_AUTO_RELOAD

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

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

EXPLAIN_TEMPLATE_LOADING

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

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

MAX_COOKIE_SIZE

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

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

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

Изменено в версии 2.3: ENV был удален.

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

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

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

# Example configuration
SECRET_KEY = '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'

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

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

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

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

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

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

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

Помимо указания на файлы конфигурации с помощью переменных окружения, вам может быть полезно (или необходимо) управлять значениями конфигурации непосредственно из окружения. 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/

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

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.

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

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

  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 чтобы увидеть, какое значение задано для префикса.

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

© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/3.0.x/config/

Spec-Zone.ru

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