Optimizely Python SDK

PyPI version Build Status Coverage Status Documentation Status Apache 2.0

This repository houses the official Python SDK for use with Optimizely Full Stack and Optimizely Rollouts.

Optimizely Full Stack is A/B testing and feature flag management for product development teams. Experiment in any application. Make every feature on your roadmap an opportunity to learn. Learn more at https://www.optimizely.com/platform/full-stack/, or see the Full Stack documentation.

Optimizely Rollouts is free feature flags for development teams. Easily roll out and roll back features in any application without code deploys. Mitigate risk for every feature on your roadmap. Learn more at https://www.optimizely.com/rollouts/, or see the Rollouts documentation.

Getting Started

Installing the SDK

The SDK is available through PyPi.

To install:

pip install optimizely-sdk

Feature Management Access

To access the Feature Management configuration in the Optimizely dashboard, please contact your Optimizely account executive.

Using the SDK

You can initialize the Optimizely instance in three ways: with a datafile, by providing an sdk_key, or by providing an implementation of BaseConfigManager. Each method is described below.

  1. Initialize Optimizely with a datafile. This datafile will be used as the source of ProjectConfig throughout the life of Optimizely instance:

    optimizely.Optimizely(
      datafile
    )
    
  2. Initialize Optimizely by providing an ‘sdk_key’. This will initialize a PollingConfigManager that makes an HTTP GET request to the URL (formed using your provided sdk key and the default datafile CDN URL template) to asynchronously download the project datafile at regular intervals and update ProjectConfig when a new datafile is received. A hard-coded datafile can also be provided along with the sdk_key that will be used initially before any update:

    optimizely.Optimizely(
      sdk_key='put_your_sdk_key_here'
    )
    

    If providing a datafile, the initialization will look like:

    optimizely.Optimizely(
      datafile=datafile,
      sdk_key='put_your_sdk_key_here'
    )
    
  3. Initialize Optimizely by providing a ConfigManager that implements BaseConfigManager. You may use our PollingConfigManager or AuthDatafilePollingConfigManager as needed:

    optimizely.Optimizely(
      config_manager=custom_config_manager
    )
    

PollingConfigManager

The PollingConfigManager asynchronously polls for datafiles from a specified URL at regular intervals by making HTTP requests.

polling_config_manager = PollingConfigManager(
    sdk_key=None,
    datafile=None,
    update_interval=None,
    url=None,
    url_template=None,
    logger=None,
    error_handler=None,
    notification_center=None,
    skip_json_validation=False
)

Note: You must provide either the sdk_key or URL. If you provide both, the URL takes precedence.

sdk_key The sdk_key is used to compose the outbound HTTP request to the default datafile location on the Optimizely CDN.

datafile You can provide an initial datafile to bootstrap the ProjectConfigManager so that it can be used immediately. The initial datafile also serves as a fallback datafile if HTTP connection cannot be established. The initial datafile will be discarded after the first successful datafile poll.

update_interval The update_interval is used to specify a fixed delay in seconds between consecutive HTTP requests for the datafile.

url The target URL from which to request the datafile.

url_template A string with placeholder {sdk_key} can be provided so that this template along with the provided sdk key is used to form the target URL.

You may also provide your own logger, error_handler, or notification_center.

AuthDatafilePollingConfigManager

The AuthDatafilePollingConfigManager implements PollingConfigManager and asynchronously polls for authenticated datafiles from a specified URL at regular intervals by making HTTP requests.

auth_datafile_polling_config_manager = AuthDatafilePollingConfigManager(
    datafile_access_token,
    *args,
    **kwargs
)

Note: To use AuthDatafilePollingConfigManager, you must create a secure environment for your project and generate an access token for your datafile.

datafile_access_token The datafile_access_token is attached to the outbound HTTP request header to authorize the request and fetch the datafile.

Advanced configuration

The following properties can be set to override the default configurations for PollingConfigManager and AuthDatafilePollingConfigManager.

Property Name

Default Value

Description

sdk_key

None

Optimizely project SDK key

datafile

None

Initial datafile, typically sourced from a local cached source

update_interval

5 minutes

Fixed delay between fetches for the datafile

url

None

Custom URL location from which to fetch the datafile

url_template

PollingConfigManager:
https://cdn.optimizely.com/datafiles/{sdk_key}.json
AuthDatafilePollingConfigManager:
https://config.optimizely.com/datafiles/auth/{sdk_key}.json

Parameterized datafile URL by SDK key

A notification signal will be triggered whenever a new datafile is fetched and Project Config is updated. To subscribe to these notifications, use:

notification_center.add_notification_listener(NotificationTypes.OPTIMIZELY_CONFIG_UPDATE, update_callback)

For Further details see the Optimizely Full Stack documentation to learn how to set up your first Python project and use the SDK.

Development

Building the SDK

Build and install the SDK with pip, using the following command:

pip install -e .

Unit tests

Running all tests

To get test dependencies installed, use a modified version of the install command:

pip install -e '.[test]'

You can run all unit tests with:

pytest

Running all tests in a file

To run all tests under a particular test file you can use the following command:

pytest tests.<file_name_without_extension>

For example, to run all tests under test_event_builder, the command would be:

pytest tests/test_event_builder.py

Running all tests under a class

To run all tests under a particular class of tests you can use the following command:

pytest tests/<file_name_with_extension>::ClassName

For example, to run all tests under test_event_builder.EventTest, the command would be:

pytest tests/test_event_builder.py::EventTest

Running a single test

To run a single test you can use the following command:

pytest tests/<file_name_with_extension>::ClassName::test_name

For example, to run test_event_builder.EventTest.test_init, the command would be:

pytest tests/test_event_builder.py::EventTest::test_init