Безопасно ли перезаписывать конфигурацию приложения после первого назначения конфигурации (и не отменяет ли это преимущества шаблона facotry)?

Здравствуйте, у нас есть несколько способов настроить конфигурации приложений во Flask.

  1. ENV var прямо в cmd перед запуском flask

  2. app.config['xxx']

  3. app.config.from_object (модуль или класс)

  4. app.config.from_pyfile (файл)

  5. app.config.from_envvar (FILEPATH_ENVVAR)

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

Поэтому мне интересно, безопасно ли использовать несколько методов сверху?

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

Шаг 1. Используйте метод 1 перед запуском приложения (например, чтобы установить ENVvar секретный ключ или настроитьENVvar, который можно проверить в коде на шаге 2, чтобы решить, применять ли класс настроек dev/prod config или установитьENV var PATH_TO_SOMECONFIGFILE)

Шаг 2. Сразу после инициализации объекта приложения используйте метод 3 (чтобы установить производственные настройки по умолчанию или проверитьENV var, установленный на шаге выше, чтобы вызвать соответствующий класс dev / prod).

Шаг 3. Сразу после указанного выше шага используйте метод 4 или 5, чтобы обновить настройки конфигурации.

Так будут ли настройки из шага 3 правильно перезаписать все предыдущие (ранее установленные) настройки? И это хорошая практика? И не отменяет ли это преимущества использования фабричного шаблона, поскольку я читал, что отказ от фабричного шаблона (например, при модульном тестировании) может привести к определенной конфигурации, если обновление не будет применяться правильно. Следовательно, создайте фабричный шаблон, чтобы получить свежий объект с примененной необходимой конфигурацией.

1 ответ

Решение

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

Поэтому мне интересно, безопасно ли использовать несколько методов сверху?

Да. И на самом деле рекомендуется использовать несколько способов загрузки конфигурации (см. Ниже, почему).

Так будут ли настройки из шага 3 правильно перезаписать все предыдущие (ранее установленные) настройки? И это хорошая практика?

Да. И обычно лучший способ узнать что-то - это попробовать. Итак, я приведу вам пример ниже, используя классы и наследование, просто чтобы доказать, как работает переопределение (вы можете вставить это в модуль Python и запустить его, если у вас установлен Flask), но вы должны продолжить и поэкспериментировать со всеми из них. Вышеупомянутые методы, о которых вы читали, смешайте и сопоставьте их, чтобы закрепить свои знания.

from flask import Flask


class Config:
    LOGGING_CONFIGURATION = None
    DATABASE = None

class DevelopmentConfig(Config):
    LOGGING_CONFIGURATION = 'Development'
    DATABASE = 'development.db'

class TestConfig(Config):
    LOGGING_CONFIGURATION = 'Test'
    DATABASE = 'test.db'


def create_app(config):
    app = Flask(__name__)
    app.config.from_object(Config)  # we load the default configuration
    print(app.config['LOGGING_CONFIGURATION'], app.config['DATABASE'])
    app.config.from_object(config)  # we override with the parameter config
    print(app.config['LOGGING_CONFIGURATION'], app.config['DATABASE'])
    return app


if __name__ == '__main__':
    app = create_app(DevelopmentConfig)
    test_app = create_app(TestConfig)  # you do this during tests

выходы

None None
Development development.db
None None
Test test.db

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

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

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


Дополнительные пояснения

Способ разработки Flask обычно требует, чтобы конфигурация была доступна при запуске приложения, и вам обычно требуется НЕКОТОРЫЙ ВИД конфигурации, потому что, в зависимости от вашей среды, вы можете захотеть изменить различные параметры, например:

  • SECRET KEY, например (если вы используете Cookies, например)
  • переключить режим DEBUG (вы определенно не хотите использовать его в производстве, но вы делаете это в режиме разработки)
  • с использованием другой БАЗЫ ДАННЫХ (которая может быть путем к другому файлу, если вы используете SQLITE3, что очень полезно в тестах, где вы не хотите использовать производственную базу данных)
  • с использованием другой конфигурации ведения журнала (возможно, вам понадобится записывать критическую информацию в ФАЙЛ в производстве, но в процессе разработки вы захотите, чтобы все регистрировалось в КОНСОЛИ для целей отладки)
  • так далее

Теперь вы видите, что, поскольку вам нужны разные настройки для разных конфигураций, вам понадобится какой-то механизм для переключения между конфигурациями, поэтому использование всех этих методов вместе полезно и рекомендуется, потому что обычно вы загружаете какой-то Конфигурация ПО УМОЛЧАНИЮ и переопределение соответственно в зависимости от среды (ПРОИЗВОДСТВО, РАЗРАБОТКА и т. Д.).

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

У меня также есть приложение с открытым исходным кодом, созданное с помощью Flask, где я использовал классы и наследование для загрузки различных конфигураций, основанных на разных средах, и пошел еще дальше, чтобы настроить их. Так что я не только загружаю, скажем, конфигурацию РАЗРАБОТКИ, но даже настраиваю ее, если захочу. Примеры здесь, и я загружаю их отсюда. Попытайтесь понять механизм, с помощью которого я загружаю конфигурацию, это вам поможет.

Редактировать:

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

  • Неважно, как вы загружаете или переопределяете свою конфигурацию. Все настройки будут загружены вconfigтолковый словарь. Это принадлежит объекту Flask. Здесь будет жить ваша конфигурация.
  • Так что неважно, делаете ли вы:
  # override a setting if it exists or add it if it doesn't
  # just like you would do in a normal dictionary
  app.config[key] = value

  # this will either override all the values that are loaded
  # from that object or it will add them
  app.config.from_pyobject(object)

  # same as above, and the same goes for any method you use to add/override
  app.config.from_pyfile(filename)

То же самое касается любого другого метода, не указанного здесь, который может загружать / отменять настройки. Все они имеют одинаковый приоритет, просто будьте осторожны с порядком, в котором вы переопределяете, конфигурация, которую вы загружаете последней, - это та, которую приложение будет использовать.


Слово совета

Попытайтесь загрузить свою конфигурацию вместе со всеми ее основными параметрами, независимо от вашей среды, сразу после запуска приложения и не изменяйте их с этого момента. Если вы обнаружите, что изменяете множество настроек из разных частей приложения, после того, как приложение запущено (т.е. вы делаете многоapp[value] = another_value), попробуйте переосмыслить свой дизайн, так как это нестабильная реализация. Что делать, если часть приложения ожидает параметр, который не был установлен другой частью приложения? Не делай этого.

Другие вопросы по тегам