OpenFeature Providers

OpenFeature Python Provider

ConfigDirector Provider for the OpenFeature Python SDK

Introduction

The OpenFeature Python Provider is intended to be used in combination with the OpenFeature Python SDK. The provider wraps the ConfigDirector Python SDK.

The minimum Python version supported is 3.10.

The provider is thread safe. Register one instance per process when your application starts, and shut OpenFeature down when it stops. Evaluations read config state the provider already holds in memory, so they make no network calls on the request path.

Installation

The provider can be installed from PyPI: https://pypi.org/project/configdirector-openfeature-server-provider/

The OpenFeature Python SDK (openfeature-sdk) and the ConfigDirector Python SDK are included as dependencies.

pip install configdirector-openfeature-server-provider

Configure and initialize the client

  1. Create an instance of the provider using your server SDK key. You can retrieve a server SDK key for each environment under SDK Keys in the dashboard's navigation panel.
  2. Set the OpenFeature provider.
  3. Get a client instance from OpenFeature.
config_director_setup.py
from configdirector_openfeature import ConfigDirectorProvider
from openfeature import api

api.set_provider_and_wait(ConfigDirectorProvider("YOUR-SERVER-SDK-KEY"))
client = api.get_client()
Server SDK keys are secret values. Do not commit them to your source code repository. Provide them at runtime via environment variables instead.

set_provider_and_wait blocks until the initial config state arrives or the configured timeout elapses, and it does not raise on a connection failure. Until config state arrives, evaluations return the default value with the PROVIDER_NOT_READY error code, and the provider continues to connect in the background.

set_provider_and_wait requires openfeature-sdk version 0.10 or newer. On older versions use api.set_provider, which waits for the provider to initialize.

Additional configuration options

Additional configuration options can be passed into the provider as keyword arguments of the constructor.

For example, the metadata can be provided like this:

config_director_setup.py
from configdirector import Metadata
from configdirector_openfeature import ConfigDirectorProvider

provider = ConfigDirectorProvider(
    "YOUR-SERVER-SDK-KEY",
    metadata=Metadata(app_name="YOUR-APP-NAME", app_version="1.0.2"),
)

The provider accepts the same metadata, connection, logger, log_level, and telemetry options as the Python SDK client, refer to the additional configuration options section of the Python SDK for a full list.

Shut down

Shutting OpenFeature down closes the provider, which closes its connections and reports any pending telemetry:

main.py
import atexit

from openfeature import api

atexit.register(api.shutdown)

Retrieve config values

To retrieve config values, use the OpenFeature client:

main.py
boolean_value = client.get_boolean_value("my-config-key", False)

string_value = client.get_string_value("my-string-config-key", "Default")

Each OpenFeature getter maps to a ConfigDirector config type:

OpenFeature getterConfigDirector config value
get_boolean_valueBoolean
get_string_valueString or enum
get_integer_value, get_float_valueNumber
get_object_valueJSON object or JSON array

get_object_value returns the parsed JSON, a dict for a JSON object or a list for a JSON array:

main.py
settings = client.get_object_value("my-json-config-key", {})
theme = settings.get("theme")

For additional information regarding the OpenFeature client refer to the OpenFeature Python SDK documentation.

Evaluation details

The detailed getters of the OpenFeature client, such as get_boolean_details, report why an evaluation produced the value that it did:

OutcomeReasonError code
A value was foundTARGETING_MATCH
The config carries no valueDEFAULT
The config key is unknownERRORFLAG_NOT_FOUND
No config state has arrived yetERRORPROVIDER_NOT_READY
The value does not match the requested typeERRORTYPE_MISMATCH

When a value was found, the variant is ConfigDirector's identifier for that value. In every other case the default value is returned.

User context

The user context can be provided as the third argument to value getter functions of the OpenFeature client. The OpenFeature Python provider evaluates targeting rules locally without additional network calls for different contexts.

main.py
from openfeature.evaluation_context import EvaluationContext

context = EvaluationContext(
    "12345",  # In OpenFeature, the targeting key represents the context's user ID
    {
        "name": "Example User",
        # Any arbitrary traits which can be referenced in targeting rules
        "traits": {"region": "North America"},
    },
)

boolean_value = client.get_boolean_value("my-config-key", False, context)

The evaluation context maps onto the ConfigDirector user context as follows:

OpenFeature evaluation contextConfigDirector user context
The targeting key, or otherwise an id attributeid
The name attributename
The traits mapping attributetraits
The boolean anonymous attributeanonymous

For additional information regarding the OpenFeature client refer to the OpenFeature Python SDK documentation.

Events

The provider emits PROVIDER_CONFIGURATION_CHANGED whenever configs are updated on the dashboard or via the admin API, carrying the keys of the configs in the update:

main.py
from openfeature import api
from openfeature.event import EventDetails, ProviderEvent


def on_configuration_changed(details: EventDetails) -> None:
    print(f"Configs updated: {details.flags_changed}")


api.add_handler(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, on_configuration_changed)

It emits PROVIDER_READY when the initial config state arrives after set_provider_and_wait has already returned.