Поделиться через


Управление функциями Python

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

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

Ниже приведены некоторые преимущества использования библиотеки управления функциями Python:

  • Общее соглашение об управлении функциями

  • Низкий барьер для входа

    • Поддерживает настройку флага функций JSON
  • Управление временем существования флага компонентов

    • Значения конфигурации могут изменяться в режиме реального времени; Флаги функций могут быть согласованы по всему запросу
  • Простые и сложные сценарии, описанные

    • Включение и отключение функций с помощью декларативного файла конфигурации
    • Динамическое вычисление состояния функции на основе вызова сервера

    Библиотека управления функциями Python открытый код. Дополнительные сведения см. в репозитории GitHub.

Флаги функций

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

Фильтры компонентов

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

Например, можно создать фильтр функций браузера Microsoft Edge. Этот фильтр функций активирует все функции, подключенные к нему, если HTTP-запрос поступает из Microsoft Edge.

Конфигурация флага компонента

Словарь Python используется для определения флагов функций. Словарь состоит из имен компонентов в виде ключей и объектов флага признаков в качестве значений. Объект флага компонента — это словарь, содержащий conditions ключ, который сам содержит client_filters ключ. Ключ client_filters — это список фильтров компонентов, которые используются для определения необходимости включения функции.

Объявление флага функции

Библиотека управления функциями поддерживает json в качестве источника флага компонента. Ниже приведен пример формата, используемого для настройки флагов функций в JSON-файле.

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "FeatureT",
                "enabled": "true"
            },
            {
                "id": "FeatureU",
                "enabled": "false"
            },
            {
                "id": "FeatureV",
                "enabled": "true",
                "conditions": {
                    "client_filters": [
                        {
                            "name": "Microsoft.TimeWindow",
                            "parameters": {
                                "Start": "Wed, 01 May 2019 13:59:59 GMT",
                                "End": "Mon, 01 Jul 2019 00:00:00 GMT"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

Раздел feature_management документа JSON используется по соглашению для загрузки параметров флага компонентов. Этот feature_flags раздел содержит список флагов функций, загруженных в библиотеку. В приведенном выше разделе мы видим три различных компонента. Функции определяют фильтры функций с помощью client_filters свойства внутри conditions. В фильтрах функций, для которого мы видимenabled, нет определенных FeatureTфильтров, что приводит к FeatureT постоянному возврату true . FeatureUсовпадает с тем, что FeatureT enabled false при этом функция всегда возвращается.false FeatureV указывает фильтр признаков с именем Microsoft.TimeWindow. FeatureV пример настраиваемого фильтра компонентов. Мы видим в примере, что фильтр имеет parameters свойство. Свойство parameters используется для настройки фильтра. В этом случае настроено время начала и окончания для активной функции.

Подробные схемы feature_management раздела можно найти здесь.

Дополнительно. Использование двоеточия ":" запрещено в именах флагов признаков.

Объявление "Вкл/выкл."

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

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "FeatureT",
                "enabled": "true"
            },
            {
                "id": "FeatureX",
                "enabled": "false"
            }
        ]
    }
}

Requirement_type

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

  • Any означает, что только один фильтр должен иметь значение true для включения функции.
  • All означает, что каждый фильтр должен иметь значение true для включения функции.

All Изменение requirement_type обхода. Во-первых, если фильтров нет, функция отключена. Затем фильтры функций проходят по одному из фильтров, пока один из фильтров не решит, что эта функция должна быть отключена. Если фильтр не указывает, что функция должна быть отключена, она считается включенной.

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "FeatureW",
                "enabled": "true",
                "conditions": {
                    "requirement_type": "All",
                    "client_filters": [
                        {
                            "name": "Microsoft.TimeWindow",
                            "parameters": {
                                "Start": "Wed, 01 May 2019 13:59:59 GMT",
                                "End": "Mon, 01 Jul 2019 00:00:00 GMT"
                            }
                        },
                        {
                            "name": "Percentage",
                            "parameters": {
                                "Value": "50"
                            }
                        }
                    ]
                }
            },
        ]
    }
}

В приведенном выше примере указывает значение requirement_type All, FeatureW что означает, что все его фильтры должны иметь значение true, чтобы функция была включена. В этом случае функция включена для 50% пользователей в течение указанного периода времени.

Потребление

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

…
feature_manager = FeatureManager(feature_flags)
…
if feature_manager.is_enabled("FeatureX"):
    # Do something

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

Реализация фильтра компонентов

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

В следующем фрагменте кода показано, как добавить настраиваемый фильтр MyCustomFilterкомпонентов.

feature_manager = FeatureManager(feature_flags, feature_filters=[MyCustomFilter()])

Фильтры компонентов регистрируются, предоставляя их свойству feature_filters при создании FeatureManager. Если для пользовательского фильтра функций требуется любой контекст, их можно передать при вызове is_enabled kwargs.

Атрибут псевдонима фильтра

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

Идентификатор фильтра функций можно переопределить с помощью идентификатора @FeatureFilter.alias("MyFilter"). Фильтр компонентов можно декорировать этим атрибутом, чтобы объявить имя, которое должно использоваться в конфигурации для ссылки на этот фильтр компонентов в флаге компонента.

Отсутствующие фильтры функций

Если функция настроена для определенного фильтра компонентов и этот фильтр компонентов не зарегистрирован, ValueError при оценке компонента возникает исключение.

Встроенные фильтры функций

Существует два фильтра функций, которые поставляется с пакетом FeatureManagement : TimeWindowFilterи TargetingFilter.

Каждый из встроенных фильтров функций имеет собственные параметры. Ниже приведен список фильтров функций вместе с примерами.

Microsoft.TimeWindow

Этот фильтр предоставляет возможность включить функцию на основе периода времени. Если указан только End этот параметр, функция рассматривается до этого времени. Если указан только Start этот параметр, функция рассматривается во всех точках после этого времени.

"client_filters": [
    {
        "name": "Microsoft.TimeWindow",
        "parameters": {
            "Start": "Wed, 01 May 2019 13:59:59 GMT",
            "End": "Mon, 01 Jul 2019 00:00:00 GMT"
        }
    }
]     

Microsoft.Targeting

Этот фильтр предоставляет возможность включить функцию для целевой аудитории. Подробное объяснение целевого назначения объясняется в приведенном ниже разделе о целевом объекте . Параметры фильтра включают Audience объект, описывающий пользователей, групп, исключенных пользователей и групп, а также процент базы пользователей по умолчанию, который должен иметь доступ к этой функции. Каждый объект группы, указанный в Groups разделе, также должен указывать, какой процент членов группы должен иметь доступ. Если пользователь указан в Exclusion разделе, либо непосредственно, либо если пользователь находится в исключенной группе, функция отключена. В противном случае, если пользователь указан в Users разделе напрямую, или если пользователь находится в процентах от любого из развернутых групп или если пользователь попадает в процент развертывания по умолчанию, то этот пользователь будет включен.

"client_filters": [
    {
        "name": "Microsoft.Targeting",
        "parameters": {
            "Audience": {
                "Users": [
                    "Jeff",
                    "Alicia"
                ],
                "Groups": [
                    {
                        "Name": "Ring0",
                        "RolloutPercentage": 100
                    },
                    {
                        "Name": "Ring1",
                        "RolloutPercentage": 50
                    }
                ],
                "DefaultRolloutPercentage": 20,
                "Exclusion": {
                    "Users": [
                        "Ross"
                    ],
                    "Groups": [
                        "Ring2"
                    ]
                }
            }
        }
    }
]

Таргетинг

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

Ниже приведен пример прогрессивного развертывания для новой функции Beta:

  1. Отдельные пользователи Джефф и Алисия получают доступ к бета-версии
  2. Другой пользователь, Марк, просит принять участие и включен.
  3. Двадцать процентов группы, известной как "Ring1", включены в бета-версию.
  4. Число пользователей Ring1, включенных в бета-версию, составляет до 100 процентов.
  5. Пять процентов пользовательской базы включены в бета-версию.
  6. Процент развертывания вырос до 100 процентов, и функция полностью развернута.

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

Назначение пользователя

Можно указать пользователя непосредственно в вызове is_enabled или TargetingContext использовать для указания пользователя и необязательной группы.

# Directly specifying the user
result = is_enabled(feature_flags, "test_user")

# Using a TargetingContext
result = is_enabled(feature_flags, TargetingContext(user_id="test_user", groups=["Ring1"]))

Назначение исключения

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

"Audience": {
    "Users": [
        "Jeff",
        "Alicia"
    ],
    "Groups": [
        {
            "Name": "Ring0",
            "RolloutPercentage": 100
        }
    ],
    "DefaultRolloutPercentage": 0
    "Exclusion": {
        "Users": [
            "Mark"
        ]
    }
}

В приведенном выше примере функция включена для пользователей с именем Jeff и Alicia. Он также включен для пользователей в группе с именем Ring0. Однако если пользователь называется Mark, функция отключена независимо от того, находятся ли они в группе Ring0 или нет. Исключения занимают приоритет от остальной части фильтра целевого объекта.

Варианты

При добавлении новых функций в приложение может возникнуть время, когда функция имеет несколько различных предлагаемых вариантов проектирования. Распространенное решение для принятия решения о проектировании — это некоторая форма тестирования A/B. Тестирование A/B включает в себя предоставление другой версии функции различным сегментам пользовательской базы и выбор версии на основе взаимодействия с пользователем. В этой библиотеке эта функция включена путем представления различных конфигураций компонента с вариантами.

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

class Variant:
    def __init__(self, name: str, configuration: Any):
        self._name = name
        self._configuration = configuration

    @property
    def name(self) -> str:
        """
        The name of the variant.
        :rtype: str
        """
        return self._name

    @property
    def configuration(self) -> Any:
        """
        The configuration of the variant.
        :rtype: Any
        """
        return self._configuration

Получение вариантов

Для каждой функции можно получить вариант с помощью FeatureManagerget_variant метода.

…
variant = print(feature_manager.get_variant("TestVariants", TargetingContext(user_id="Adam"))

variantConfiguration = variant.configuration;

// Do something with the resulting variant and its configuration

Возвращаемый вариант зависит от вычисляемого пользователя, и эта информация получается из экземпляра TargetingContext.

Объявление флага функции Variant

По сравнению с обычными флагами функций флаги вариантов имеют два дополнительных свойства: variants и allocation. Это variants массив, содержащий варианты, определенные для этой функции. Свойство allocation определяет, как эти варианты должны быть выделены для функции. Как и объявление обычных флагов функций, можно настроить флаги вариантных функций в JSON-файле. Ниже приведен пример флага функции варианта.

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyVariantFeatureFlag",
                "enabled": true,
                "allocation": {
                    "default_when_enabled": "Small",
                    "group": [
                        {
                            "variant": "Big",
                            "groups": [
                                "Ring1"
                            ]
                        }
                    ]
                },
                "variants": [
                    { 
                        "name": "Big"
                    },  
                    { 
                        "name": "Small"
                    } 
                ]
            }
        ]
    }
}

Определение вариантов

Каждый вариант имеет два свойства: имя и конфигурацию. Имя используется для ссылки на конкретный вариант, а конфигурация — это значение этого варианта. Конфигурацию можно задать с помощью configuration_value свойства. configuration_value — это встроенная конфигурация, которая может быть строкой, номером, логическим объектом или объектом конфигурации. Если configuration_value значение не указано, свойство возвращаемого варианта Configuration имеет значение None.

Список всех возможных вариантов определяется для каждой функции в свойстве variants .

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyVariantFeatureFlag",
                "variants": [
                    { 
                        "name": "Big", 
                        "configuration_value": {
                            "Size": 500
                        }
                    },  
                    { 
                        "name": "Small", 
                        "configuration_value": {
                            "Size": 300
                        }
                    } 
                ]
            }
        ]
    }
}

Выделение вариантов

Процесс выделения вариантов компонента определяется свойством allocation функции.

"allocation": { 
    "default_when_enabled": "Small", 
    "default_when_disabled": "Small",  
    "user": [ 
        { 
            "variant": "Big", 
            "users": [ 
                "Marsha" 
            ] 
        } 
    ], 
    "group": [ 
        { 
            "variant": "Big", 
            "groups": [ 
                "Ring1" 
            ] 
        } 
    ],
    "percentile": [ 
        { 
            "variant": "Big", 
            "from": 0, 
            "to": 10 
        } 
    ], 
    "seed": "13973240" 
},
"variants": [
    { 
        "name": "Big", 
        "configuration_value": "500px"
    },  
    { 
        "name": "Small", 
        "configuration_value": "300px"
    } 
]

Параметр allocation компонента имеет следующие свойства:

Свойство Description
default_when_disabled Указывает, какой вариант следует использовать при запросе варианта во время отключения функции.
default_when_enabled Указывает, какой вариант следует использовать при запросе варианта, если компонент считается включенным, и другой вариант не был назначен пользователю.
user Задает вариант и список пользователей, которым должен быть назначен этот вариант.
group Задает вариант и список групп. Вариант назначается, если пользователь находится по крайней мере в одной из групп.
percentile Задает вариант и процентный диапазон, в котором вычисляемый процент пользователя должен соответствовать назначенному варианту.
seed Значение, на котором основаны процентные расчеты percentile . Процентное вычисление для конкретного пользователя будет одинаковым для всех функций, если используется одно и то же seed значение. Если значение не seed указано, то начальное значение по умолчанию создается на основе имени функции.

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

Если функция включена, диспетчер функций проверяет usergroupи percentile выделяется таким образом, чтобы назначить вариант. В этом примере, если вычисляемый пользователь называется Marsha, в группе с именем Ring1или пользователь попадает между 0 и 10-м процентилем, то указанный вариант назначается пользователю. В этом случае все назначенные пользователи возвращают Big вариант. Если ни одно из этих выделений не соответствует, пользователю назначается default_when_enabled вариант.Small

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

Переопределение состояния включено с помощью варианта

Варианты можно использовать для переопределения состояния включенного флага компонента. Переопределение предоставляет варианты возможности расширения оценки флага компонента. При вызове is_enabled флага с вариантами диспетчер функций проверяет, настроен ли вариант, назначенный текущему пользователю, переопределить результат. Переопределение выполняется с помощью необязательного свойства status_overridevariant. По умолчанию это свойство имеет значение None, что означает, что вариант не влияет на то, включен или отключен флаг. Параметр status_override позволяет варианту Enabled при выборе переопределить флаг, который необходимо включить. Параметр status_override для Disabled получения противоположной функциональности, поэтому отключение флага при выборе варианта. Невозможно переопределить функцию enabled с состоянием false переопределения.

Если вы используете флаг функции с двоичными вариантами, status_override это свойство может оказаться полезным. Он позволяет продолжать использовать API, такие как is_enabled в приложении, все в то время как преимущества новых функций, которые приходят с вариантами, такими как выделение процентиля и начальное значение.

{
    "id": "MyVariantFeatureFlag",
    "enabled": true,
    "allocation": {
        "percentile": [
            {
                "variant": "On",
                "from": 10,
                "to": 20
            }
        ],
        "default_when_enabled":  "Off",
        "seed": "Enhanced-Feature-Group"
    },
    "variants": [
        {
            "name": "On"
        },
        {
            "name": "Off",
            "status_override": "Disabled"
        }
    ]
}

В приведенном выше примере функция всегда включена. Если текущий пользователь находится в вычисляемом диапазоне процентиля от 10 до 20, On возвращается вариант. Off В противном случае возвращается вариант и, так как status_override равенDisabled, функция теперь будет считаться отключенной.

Телеметрия

При развертывании изменения флага функции часто важно проанализировать его влияние на приложение. Например, вот несколько вопросов, которые могут возникнуть:

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

Эти типы вопросов можно ответить с помощью выбросов и анализа событий оценки флага признаков. Эта библиотека при необходимости позволяет AzureMonitor создавать данные телеметрии трассировки во время оценки флага компонента с помощью OpenTelemetry.

Включение телеметрии

По умолчанию флаги компонентов не создают данные телеметрии. Чтобы опубликовать данные телеметрии для заданного флага компонента, флаг ДОЛЖЕН объявить, что он включен для выбросов телеметрии.

Для флагов компонентов, определенных в json, включение выполняется с помощью telemetry свойства.

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyFeatureFlag",
                "enabled": true,
                "telemetry": {
                    "enabled": true
                }
            }
        ]
    }
}

Приведенный выше фрагмент определяет флаг компонента с именем MyFeatureFlag , который включен для телеметрии. Для telemetry свойства объекта enabled задано значение true. Значение enabled свойства должно быть true для публикации телеметрии для флага.

Раздел telemetry флага компонента имеет следующие свойства:

Свойство Description
enabled Указывает, следует ли публиковать данные телеметрии для флага компонента.
metadata Коллекция пар "ключ-значение", моделироваемая как словарь, которая может использоваться для присоединения пользовательских метаданных о флаге компонента для оценки событий.

Кроме того, при создании FeatureManagerобратный вызов необходимо зарегистрировать для обработки событий телеметрии. Этот обратный вызов вызывается всякий раз, когда вычисляется флаг компонента, и для этого флага включена телеметрия.

feature_manager = FeatureManager(feature_flags, on_feature_evaluated=publish_telemetry)

Данные телеметрии Application Insights

Библиотека управления функциями предоставляет встроенный издатель телеметрии, который отправляет данные оценки флага компонента в Application Insights. Чтобы включить Application Insights, с помощью Azure Monitor можно установить библиотеку управления функциями pip install FeatureManagement[AzureMonitor]. Эта команда устанавливает azure-monitor-events-extension пакет, который используется для стиля телеметрии в Application Insights с помощью OpenTelemetry.

Примечание.

Пакет azure-monitor-events-extension добавляет только данные телеметрии в конвейер Open Telemetry. Регистрация Application Insights по-прежнему требуется.

from azure.monitor.opentelemetry import configure_azure_monitor

configure_azure_monitor(
        connection_string="InstrumentationKey=00000000-0000-0000-0000-000000000000"
    )

Публикация пользовательских данных телеметрии

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

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

Тег Description
feature Используемый флаг компонента.
user Идентификатор пользователя, используемый для целевого назначения.
enabled Оценивается ли флаг компонента как включенный.
Variant Назначенный вариант.
VariantAssignmentReason Причина назначения варианта.

Следующие шаги

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

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