Dev guideAPI Reference
Dev guideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

OptimizelyConfig for the Python SDK

How to get access to project configuration data within the datafile using OptimizelyConfig for the Optimizely Feature Experimentation Python SDK.

Overview

Optimizely Feature Experimentation SDKs open a well-defined set of public APIs, hiding all implementation details. However, some clients may need access to project configuration data within the datafile.

In this document, we extend our public APIs to define data models and access methods, which clients can use to access project configuration data.

OptimizelyConfig API

A public configuration data model (OptimizelyConfig) is defined below as a structured format of static Optimizely Project data.

Get OptimizelyConfig

OptimizelyConfig can be accessed from OptimizelyClient (top-level) with this public API call:

def get_optimizely_config(self)

getOptimizelyConfig returns an OptimizelyConfig instance, which includes

  • environment key
  • SDK key
  • the datafile revision number
  • all experiments mapped by their key values
  • all attributes
  • all audiences
  • all events
  • feature flags mapped by their key values
  • function to retrieve the project configuration (the datafile)

📘

Note

When the SDK datafile is updated (the client can add a notification listener for OPTIMIZELY_CONFIG_UPDATE to get notified), the client is expected to call the method to get the updated OptimizelyConfig data. See examples below.

Get datafile

To share the same datafile between multiple SDK instances (for example, in a client/server scenario), you can pass a JSON string representation of the config (the datafile) between the instances. To get the datafile, use the OptimizelyConfig object's getDatafile method. For more information, see Sharing the datafile with multiple SDK implementations.

Object model

The following shows the object model for OptimizelyConfig.

class OptimizelyConfig(object):
    def __init__(self, revision, experiments_map, features_map, sdk_key=None, environment_key=None, attributes=None, events=None,
                 audiences=None):
        self.revision = revision
        # This experiments_map is for experiments of legacy projects only.
  			# For flag projects, experiment keys are not guaranteed to be unique 
			  # across multiple flags, so this map may not include all experiments 
  			# when keys conflict.
        self.experiments_map = experiments_map
        self.features_map = features_map
        self.sdk_key = sdk_key or ''
        self.environment_key = environment_key or ''
        self.attributes = attributes or []
        self.events = events or []
        self.audiences = audiences or []


class OptimizelyExperiment(object):
    def __init__(self, id, key, variations_map, audiences=''):
        self.id = id
        self.key = key
        self.variations_map = variations_map
        self.audiences = audiences

class OptimizelyFeature(object):
        self.id = id
        self.key = key
        self.variables_map = variables_map
        self.delivery_rules = []
        self.experiment_rules = []
        
				# Deprecated. Use experiment_rules and delivery_rules. 
        self.experiments_map = experiments_map

class OptimizelyVariation(object):
    def __init__(self, id, key, feature_enabled, variables_map):
        self.id = id
        self.key = key
        self.feature_enabled = feature_enabled
        self.variables_map = variables_map


class OptimizelyVariable(object):
    def __init__(self, id, key, variable_type, value):
        self.id = id
        self.key = key
        self.type = variable_type
        self.value = value


class OptimizelyAttribute(object):
    def __init__(self, id, key):
        self.id = id
        self.key = key


class OptimizelyEvent(object):
    def __init__(self, id, key, experiment_ids):
        self.id = id
        self.key = key
        self.experiment_ids = experiment_ids


class OptimizelyAudience(object):
    def __init__(self, id, name, conditions):
        self.id = id
        self.name = name
        self.conditions = conditions

Examples

OptimizelyConfig can be accessed from OptimizelyClient (top-level) like this:

from optimizely import optimizely
optimizely_client = optimizely.Optimizely(sdk_key='<YOUR_SDK_KEY')

config = optimizely_client.get_optimizely_config()

print('REVISION ', config.revision)
print('SDK KEY ', config.sdk_key)
print('ENV KEY ', config.environment_key)

print("[OptimizelyConfig] revision = ", config.revision)
print("[OptimizelyConfig] sdk_key = ", config.sdk_key)
print("[OptimizelyConfig] environment_key = ", config.environment_key)

print("[OptimizelyConfig] attributes:")
for attribute in config.attributes:
    print('[optimizelyConfig]  - (id, key) ', attribute.id, attribute.key)

print("[OptimizelyConfig] audiences:")
for audience in config.audiences:
    print('[OptimizelyConfig]  - (id, name, conditions) ', audience.id, audience.name, audience.conditions)

print("[OptimizelyConfig] events:")
for event in config.events:
    print("[OptimizelyConfig]  - (id, key, experimentIds) ", event.id, event.key, event.experiment_ids)

# all flags
flags = config.features_map.values()
print('[OptimizelyConfig]  - flags ', flags)

flag_keys = config.features_map.keys()  # swift
print('[OptimizelyConfig]  - flag keys ', flag_keys)

for flag_key in flag_keys:
    flag = config.features_map[flag_key]

    experiment_rules = flag.experiment_rules
    delivery_rules = flag.delivery_rules

    print(experiment_rules)
    print(delivery_rules)

    # use experiment rules and delivery rules and other flag data here...
    for experiment in experiment_rules:
        print("[OptimizelyConfig]  - experiment rule-key = ", experiment.key)
        print("[OptimizelyConfig]  - experiment audiences = ", experiment.audiences)
        print("[OptimizelyConfig]  - experiment variations map = ", experiment.variations_map)

        variations_map = experiment.variations_map
        variation_keys = variations_map.keys()

        for variation_key in variation_keys:
            print("[OptimizelyConfig]  - variation = ", variation_key)       # not the same as in swift!

            map_of_variables = variations_map[variation_key].variables_map
            variable_keys = map_of_variables.keys()

            for variable_key in variable_keys:
                variable = map_of_variables[variable_key]
                print('[OptimizelyConfig]  - variable = ', variable_key, variable.value)

    for delivery in delivery_rules:
        print("[OptimizelyConfig]  - delivery rule-key = ", delivery.key)
        print("[OptimizelyConfig]  - delivery audiences = ", delivery.audiences)

# listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
def on_config_update_listener(*args):
    config = optimizely_client.get_optimizely_config()

optimizely_client.notification_center.add_notification_listener(
    enums.NotificationTypes.OPTIMIZELY_CONFIG_UPDATE, on_config_update_listener)