Compartir vía


Administración de características de Python

Administración de características

Administración de características

La biblioteca de administración de características de Python proporciona una manera de desarrollar y exponer la funcionalidad de la aplicación en función de las marcas de características. Una vez desarrollada una nueva característica, muchas aplicaciones tienen requisitos especiales, como cuándo se debe habilitar la característica y en qué condiciones. Esta biblioteca proporciona una manera de definir estas relaciones y también se integra en patrones de código de Python comunes para hacer posible la exposición de estas características.

Las marcas de características proporcionan una manera de que las aplicaciones de Python activen o desactiven dinámicamente las características. Los desarrolladores pueden usar marcas de características en casos de uso simples, como instrucciones condicionales.

Estas son algunas de las ventajas de usar la biblioteca de administración de características de Python:

  • Una convención común para la administración de características

  • Baja barrera a entrada

    • Admite la configuración de la marca de características JSON
  • Administración de la duración de la marca de características

    • Los valores de configuración pueden cambiar en tiempo real; las marcas de características pueden ser coherentes en toda la solicitud
  • Escenarios sencillos a complejos cubiertos

    • Activar o desactivar características mediante el archivo de configuración declarativo
    • Evaluar dinámicamente el estado de la característica en función de la llamada al servidor

    La biblioteca de administración de características de Python es de código abierto. Para obtener más información, visite el repositorio de GitHub.

Marcas de característica

Las marcas de características se componen de dos partes, un nombre y una lista de filtros de características que se usan para activar la característica.

Filtros de características

Los filtros de características definen un escenario para cuando se debe habilitar una característica. Cuando se evalúa si una característica está activada o desactivada, se recorre su lista de filtros de características hasta que uno de los filtros decide que la característica debe estar habilitada. En este momento, la característica se considera habilitada y se recorre a través de los filtros de características se detiene. Si no hay ningún filtro de características que indique que la característica debe estar habilitada, se considera deshabilitada.

Por ejemplo, se podría diseñar un filtro de características del explorador Microsoft Edge. Este filtro de características activaría las características a las que está asociada siempre que una solicitud HTTP provendría de Microsoft Edge.

Configuración de la marca de características

Se usa un diccionario de Python para definir marcas de características. El diccionario se compone de nombres de características como claves y objetos de marca de características como valores. El objeto de marca de característica es un diccionario que contiene una clave conditions, que contiene la clave client_filters. La clave client_filters es una lista de filtros de características que se usan para determinar si se debe habilitar la característica.

Declaración de la marca de características

La biblioteca de administración de características admite json como origen de marca de característica. A continuación se muestra un ejemplo del formato usado para configurar marcas de características en un archivo 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"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

La sección feature_management del documento json se usa por convención para cargar la configuración de la marca de características. La sección feature_flags es una lista de las marcas de características que se cargan en la biblioteca. En la sección anterior, vemos tres características diferentes. Las características definen sus filtros de características usando la propiedad client_filters, dentro de conditions. En los filtros de características para FeatureT, vemos que enabled está activado sin filtros definidos, lo que resulta en que FeatureT siempre devuelve true . FeatureU es igual que FeatureT pero con enabled es false dando como resultado que la característica siempre devuelva false. FeatureV especifica un filtro de características denominado Microsoft.TimeWindow. FeatureV es un ejemplo de un filtro de características configurable. Podemos ver en el ejemplo que el filtro tiene una propiedad parameters. La propiedad parameters se usa para configurar el filtro. En este caso, se configuran las horas de inicio y finalización de la característica que se va a activar.

Puede encontrar el esquemafeature_management detallado de la sección aquí.

Avanzadas: El uso de dos puntos ":" está prohibido en los nombres de marcas de características.

Declaración activado/desactivado

En el fragmento de código siguiente se muestra una manera alternativa de definir una característica que se puede usar para las características activadas y desactivadas.

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

Tipo de requisito

La propiedad requirement_type de una marca de característica se usa para determinar si los filtros deben usar Any o All lógica al evaluar el estado de una característica. Si no se especifica requirement_type, el valor predeterminado es Any.

  • Any significa que solo un filtro debe evaluarse como true para que se habilite la característica.
  • All significa que cada filtro debe evaluarse como true para que se habilite la característica.

Un requirement_type de All cambia el recorrido. En primer lugar, si no hay ningún filtro, la característica está deshabilitada. A continuación, los filtros de características se recorren hasta que uno de los filtros decide que la característica debe deshabilitarse. Si no hay ningún filtro que indique que la característica debe deshabilitarse, se considera habilitada.

{
    "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"
                            }
                        }
                    ]
                }
            },
        ]
    }
}

En el ejemplo anterior, FeatureW especifica un requirement_type de All, lo que significa que todos sus filtros deben evaluarse como true para que se habilite la característica. En este caso, la característica está habilitada para el 50 % de los usuarios durante el período de tiempo especificado.

Consumo

La forma básica de administración de características es comprobar si está habilitada una marca de característica y, a continuación, realizar acciones en función del resultado. La comprobación del estado de una marca de característica se realiza a través del método is_enabled de FeatureManager.

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

El feature_flags proporcionado para FeatureManager puede ser AzureAppConfigurationProvider o un diccionario de marcas de características.

Implementación de un filtro de características

La creación de un filtro de características proporciona una manera de habilitar las características en función de los criterios que defina. Para implementar un filtro de características, se debe implementar la interfaz FeatureFilter. FeatureFilter tiene un único método denominado evaluate. Cuando una característica especifica que se puede habilitar para un filtro de características, se llama al método evaluate. Si evaluate devuelve true, significa que la característica debe estar habilitada.

En el fragmento de código siguiente se muestra cómo agregar un filtro de características personalizado MyCustomFilter.

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

Los filtros de características se registran al proporcionarlos a la propiedad feature_filters al crear FeatureManager. Si un filtro de características personalizado necesita algún contexto, se pueden pasar al llamar a is_enabled usando kwargs.

Atributo de alias de filtro

Cuando se registra un filtro de características para una marca de característica, el nombre del filtro se usa como alias de forma predeterminada.

El identificador del filtro de características se puede invalidar mediante @FeatureFilter.alias("MyFilter"). Un filtro de características se puede decorar con este atributo para declarar el nombre que se debe usar en la configuración para hacer referencia a este filtro de características dentro de una marca de característica.

Faltan filtros de características

Si una característica está configurada para ser habilitada para un filtro de características específico y ese filtro de características no está registrado, se produce una excepción ValueError cuando se evalúa la característica.

Filtros de características integrados

Hay dos filtros de características que vienen con el paquete FeatureManagement: TimeWindowFilter y TargetingFilter.

Cada uno de los filtros de características integrados tiene sus propios parámetros. Esta es la lista de filtros de características junto con ejemplos.

Microsoft.TimeWindow

Este filtro proporciona la capacidad de habilitar una característica basada en un período de tiempo. Si solo se especifica End, la característica se tiene en cuenta hasta ese momento. Si solo se especifica Start, la característica se considera en todos los puntos después de ese tiempo.

"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

Este filtro proporciona la capacidad de habilitar una característica para una audiencia de destino. Una explicación detallada de la segmentación se explica en la sección destino siguiente. Los parámetros de filtro incluyen un objeto Audience que describe usuarios, grupos, usuarios o grupos excluidos y un porcentaje predeterminado de la base de usuarios que debe tener acceso a la característica. Cada objeto de grupo que aparece en la sección Groups también debe especificar el porcentaje de los miembros del grupo que deben tener acceso. Si se especifica un usuario en la sección Exclusion, ya sea directamente o si el usuario está en un grupo excluido, la característica está deshabilitada. De lo contrario, si un usuario se especifica directamente en la sección de Users, o si el usuario está en el porcentaje incluido de cualquiera de los lanzamientos de grupo, o si el usuario entra en el porcentaje de lanzamiento predeterminado, ese usuario tendrá habilitada la característica.

"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"
                    ]
                }
            }
        }
    }
]

Selección de destino

El destino es una estrategia de administración de características que habilita a los desarrolladores implementar progresivamente nuevas características en su base de usuarios. La estrategia se basa en el concepto de dirigirse a un conjunto de usuarios conocidos como destino audiencia. Un público se compone de usuarios específicos, grupos, usuarios o grupos excluidos y un porcentaje designado de toda la base de usuarios. Los grupos que se incluyen en la audiencia se pueden dividir más en porcentajes de sus miembros totales.

En los pasos siguientes se muestra un ejemplo de una implementación progresiva para una nueva característica "Beta":

  1. A los usuarios individuales, Jeff y Alicia se les concede acceso a la versión beta
  2. Otro usuario, Mark, pide participar y está incluido.
  3. El veinte por ciento de un grupo conocido como "Ring1" se incluye en la versión Beta.
  4. El número de usuarios "Ring1" incluidos en la versión beta aumenta hasta el 100 %.
  5. El cinco por ciento de la base de usuarios se incluye en la versión beta.
  6. El porcentaje de lanzamiento se aumenta hasta el 100 % y la característica se implementa por completo.

Esta estrategia para implementar una característica está integrada en la biblioteca a través del filtro de característicasMicrosoft.Targeting incluido.

Definición de destinos de usuarios

Se puede especificar un usuario directamente en la llamada a is_enabled o se puede usar TargetingContext para especificar el usuario y el grupo opcional.

# 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"]))

Exclusión de destino

Al definir una audiencia, los usuarios y grupos se pueden excluir de la audiencia. Las exclusiones son útiles cuando se está implementando una característica para un grupo de usuarios, pero es necesario excluir del lanzamiento a unos pocos usuarios o grupos. La exclusión se define agregando una lista de usuarios y grupos a la propiedad Exclusion del público.

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

En el ejemplo anterior, la característica está habilitada para los usuarios denominados Jeff y Alicia. También está habilitado para los usuarios del grupo denominado Ring0. Sin embargo, si el usuario se denomina Mark, la característica está deshabilitada, independientemente de si están en el grupo Ring0 o no. Las exclusiones tienen prioridad sobre el resto del filtro de destino.

Variantes

Cuando se agregan nuevas características a una aplicación, puede haber un momento en el que una característica tenga varias opciones de diseño propuestas diferentes. Una solución común para decidir sobre un diseño es alguna forma de pruebas A/B. Las pruebas A/B implican proporcionar una versión diferente de la característica a distintos segmentos de la base de usuarios y elegir una versión basada en la interacción del usuario. En esta biblioteca, esta funcionalidad se habilita mediante la representación de diferentes configuraciones de una característica con variantes.

Las variantes permiten que una marca de característica sea más que una marca de activación o desactivación simple. Una variante representa un valor de una marca de característica que puede ser una cadena, un número, un valor booleano o incluso un objeto de configuración. Una marca de característica que declara variantes debe definir en qué circunstancias se debe usar cada variante, que se trata con mayor detalle en la sección Asignación de variantes.

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

Obtención de variantes

Para cada característica, se puede recuperar una variante mediante el método FeatureManager get_variant.

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

variantConfiguration = variant.configuration;

// Do something with the resulting variant and its configuration

La variante devuelta depende del usuario que se está evaluando actualmente y esa información se obtiene de una instancia de TargetingContext.

Declaración de marca de característica de variante

En comparación con las marcas de características normales, las marcas de características variantes tienen dos propiedades adicionales: variants y allocation. La propiedad variants es una matriz que contiene las variantes definidas para esta característica. La propiedad allocation define cómo se deben asignar estas variantes para la característica. Al igual que declarar marcas de características normales, puede configurar marcas de características de variantes en un archivo JSON. Este es un ejemplo de una marca de característica de variante.

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

Definición de variantes

Cada variante tiene dos propiedades: un nombre y una configuración. El nombre se usa para hacer referencia a una variante específica y la configuración es el valor de esa variante. La configuración se puede establecer mediante la propiedad configuration_value. configuration_value es una configuración insertada que puede ser una cadena, un número, un valor booleano o un objeto de configuración. Si no se especifica configuration_value, la propiedad Configuration de la variante devuelta es None.

Se define una lista de todas las variantes posibles para cada característica en la propiedad variants.

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

Asignación de variantes

El proceso de asignación de variantes de una característica viene determinado por la propiedad allocation de la característica.

"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"
    } 
]

La configuración allocation de una característica tiene las siguientes propiedades:

Propiedad Descripción
default_when_disabled Especifica qué variante se debe usar cuando se solicita una variante mientras la característica se considera deshabilitada.
default_when_enabled Especifica qué variante se debe usar cuando se solicita una variante mientras la característica se considera habilitada y no se asignó ninguna otra variante al usuario.
user Especifica una variante y una lista de usuarios a los que se debe asignar esa variante.
group Especifica una variante y una lista de grupos. La variante se asignará si el usuario está en al menos uno de los grupos.
percentile Especifica una variante y un intervalo de porcentajes en el que debe caber el porcentaje calculado del usuario para que se asigne esa variante.
seed Valor en el que se basan los cálculos porcentuales de percentile. El cálculo porcentual de un usuario específico será el mismo en todas las características si se usa el mismo valor seed. Si no se especifica ningún seed, se crea una inicialización predeterminada en función del nombre de la característica.

Si la característica no está habilitada, el administrador de características asigna la variante marcada como default_when_disabled al usuario actual, que en este caso es Small.

Si la característica está habilitada, el administrador de características comprueba las asignaciones de user, group y percentile en ese orden para asignar una variante. En este ejemplo concreto, si el usuario que se evalúa se denomina Marsha, en el grupo denominado Ring1, o el usuario tiene lugar entre el percentil 0 y el 10, la variante especificada se asigna al usuario. En este caso, todos los usuarios asignados devolverían la variante Big. Si ninguna de estas asignaciones coincide, al usuario se le asigna la variante default_when_enabled, que es Small.

La lógica de asignación es similar a el filtro de características de Microsoft.Targeting, pero hay algunos parámetros presentes en el destino que no están en la asignación y viceversa. Los resultados de la selección de destino y la asignación no están relacionados.

Invalidar el estado habilitado con una variante

Puede usar variantes para invalidar el estado habilitado de una marca de característica. La invalidación ofrece a las variantes la oportunidad de ampliar la evaluación de una marca de característica. Al llamar a is_enabled en una marca con variantes, el administrador de características comprobará si la variante asignada al usuario actual está configurada para invalidar el resultado. La invalidación se hace mediante la propiedad de variante opcional status_override. De forma predeterminada, esta propiedad se establece en None, lo que significa que la variante no afecta a si la marca se considera habilitada o deshabilitada. Establecer status_override en Enabled permite que la variante, cuando se elija, invalide una marca que se va a habilitar. Establecer status_override en Disabled proporciona la funcionalidad opuesta, por lo que deshabilitar la marca cuando se elige la variante. No se puede invalidar una característica con un estado enabled false.

Si usa una marca de característica con variantes binarias, la propiedad status_override puede ser útil. Permite seguir usando API como is_enabled en la aplicación, al tiempo que se beneficia de las nuevas características que incluyen variantes, como la asignación de percentil y la inicialización.

{
    "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"
        }
    ]
}

En el ejemplo anterior, la característica siempre está habilitada. Si el usuario actual está en el intervalo de percentil calculado de 10 a 20, se devuelve la variante On. De lo contrario, se devuelve la variante Off y, dado que status_override es igual a Disabled, la característica ahora se considerará deshabilitada.

Telemetría

Cuando se implementa un cambio de marca de característica, a menudo es importante analizar su efecto en una aplicación. Por ejemplo, estas son algunas preguntas que pueden surgir:

  • ¿Mis marcas están habilitadas o deshabilitadas según lo previsto?
  • ¿Los usuarios de destino obtienen acceso a una determinada característica según lo previsto?
  • ¿Qué variante ve un usuario determinado?

Estos tipos de preguntas se pueden responder a través de la emisión y el análisis de eventos de evaluación de marcas de características. Esta biblioteca habilita opcionalmente AzureMonitor para producir telemetría de seguimiento durante la evaluación de la marca de característica a través de OpenTelemetry.

Habilitación de telemetría

De forma predeterminada, las marcas de características no tienen telemetría emitida. Para publicar telemetría para una marca de característica determinada, la marca DEBE declarar que está habilitada para la emisión de telemetría.

Para las marcas de características definidas en json, la habilitación se realiza usando la propiedad telemetry.

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

El fragmento de código anterior define una marca de característica denominada MyFeatureFlag que está habilitada para la telemetría. La propiedad enabled del objeto telemetry se establece en true. El valor de la propiedad enabled debe ser true para publicar datos de telemetría para la marca.

La sección telemetry de una marca de característica tiene las siguientes propiedades:

Propiedad Descripción
enabled Especifica si se debe publicar la telemetría para la marca de característica.
metadata Colección de pares clave-valor, modelado como diccionario, que se pueden usar para adjuntar metadatos personalizados sobre la marca de característica a eventos de evaluación.

Además, al crear FeatureManager, debe registrarse una devolución de llamada para controlar los eventos de telemetría. Esta devolución de llamada se invoca cada vez que se evalúa una marca de característica y se habilita la telemetría para esa marca.

feature_manager = FeatureManager(feature_flags, on_feature_evaluated=publish_telemetry)

Telemetría de Application Insights

La biblioteca de administración de características proporciona un editor de telemetría integrado que envía los datos de evaluación de las marcas de características a Application Insights. Para habilitar Application Insights, la biblioteca de administración de características puede instalarse con Azure Monitor a través de pip install FeatureManagement[AzureMonitor]. Este comando instala el paquete azure-monitor-events-extension, que se utiliza para estilizar la telemetría a Application Insights usando OpenTelemetry.

Nota:

El paquete azure-monitor-events-extension solo agrega la telemetría a la canalización de telemetría abierta. El registro de Application Insights sigue siendo necesario.

from azure.monitor.opentelemetry import configure_azure_monitor

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

Publicación de telemetría personalizada

Dado que la devolución de llamada de telemetría es una función, se puede personalizar para publicar telemetría en cualquier destino deseado. Por ejemplo, la telemetría podría publicarse en un servicio de registro, una base de datos o un servicio de telemetría personalizado.

Cuando se evalúa una marca de característica y se habilita la telemetría, el administrador de características llama a la devolución de llamada de telemetría con un parámetro EvaluationEvent. EvaluationEvent contiene las propiedades siguientes:

Etiqueta Descripción
feature Marca de característica usada.
user Id. de usuario que se usa para la selección de destino.
enabled Si la marca de característica se evalúa como habilitada.
Variant Variante asignada.
VariantAssignmentReason Motivo por el que se asigna la variante.

Pasos siguientes

Para obtener información sobre cómo usar marcas de características en las aplicaciones, continúe con los siguientes inicios rápidos.

Para obtener más información sobre cómo usar los filtros de características, continúe con los siguientes tutoriales.