Доступ к конфигурации Flask как к атрибутам, а не к ключам - PullRequest
1 голос
/ 16 октября 2019

При обработке конфигурации приложения во Flask обычно рекомендуется использовать словарь config, доступный для объекта flask.Flask, например, flask.current_app.config["TESTING"].

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

class Config:
    DEBUG = False
    TESTING = False
    DATABASE_URI = 'sqlite:///:memory:'

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

class DevelopmentConfig(Config):
    DEBUG = True

# Example usage:
app = flask.Flask(__name__)
app.config.from_object(ProductionConfig)

db_uri = app.config["DATABASE_URI"]

Недостатком этого является то, что, несмотря на то, что мы определили наши ключи, используя атрибуты класса, мы обращаемся к ним с помощью строковых ключей, которые в конечном итоге ссылаются на код. Если я неправильно наберу ключ, я не получу предупреждение в своей IDE и получу KeyError во время выполнения. Я также не получаю вывод типа для объектов в конфигурации.

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

Я думал о нескольких подходах, но ни один из них не кажется идеальным:

  1. Оберните каждый ключ конфигурации в функцию, например, get_database_uri() -пока это единственный способ доступа к конфигурации, известны доступные ключи и типы их значений. Требуется написать функцию для каждого нового ключа конфигурации.
  2. Сохраните один объект Config в конфигурации Flask, например, app.config["config"] = ProductionConfig(). С помощью подсказки типа или функции-обертки мы получаем набор текста, но странно хранить объект конфигурации внутри конфигурации, и мы теряем автоматическую установку специфичных для Flack значений, таких как TESTING.
  3. Забудьте об использованииapp.config и используйте любое другое решение.

Кто-нибудь нашел более чистые решения, которые также интегрируются с конфигурацией Flask?

1 Ответ

3 голосов
/ 16 октября 2019

Класс, используемый для app.config, можно настроить путем переопределения Flask.config_class. Напишите подкласс flask.config.Config, который определяет __getattr__ для поиска ключей, и назначьте его атрибуту config_class.

from flask.app import Flask
from flask.config import Config

class AttrConfig(Config):
    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(key)

    def __dir__(self):
        out = set(self.keys())
        out.update(super().__dir__())
        return sorted(out)

class CustomFlask(Flask):
    config_class = AttrConfig

app = CustomFlask(__name__)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...