Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Python SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts.
Optimizely Feature Experimentation is A/B testing and feature 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/products/experiment/feature-experimentation/ or see our documentation at https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs/welcome. # Optimizely Python SDK
This repository houses the Python SDK for use with Optimizely Feature Experimentation and Optimizely Full Stack (legacy).
Optimizely Feature Experimentation is an A/B testing and feature management tool for product development teams that enables you to experiment at every step. Using Optimizely Feature Experimentation allows for every feature on your roadmap to be an opportunity to discover hidden insights. Learn more at Optimizely.com, or see the developer documentation.
Optimizely Rollouts is free feature flags for development teams. You can easily roll out and roll back features in any application without code deploys, mitigating risk for every feature on your roadmap.
Refer to the Python SDK's developer documentation for detailed instructions on getting started with using the SDK.
Version 5.0+
: Python 3.8+, PyPy 3.8+
Version 4.0+
: Python 3.7+, PyPy 3.7+
Version 3.0+
: Python 2.7+, PyPy 3.4+
The SDK is available through PyPi.
To install:
pip install optimizely-sdk
To access the Feature Management configuration in the Optimizely dashboard, please contact your Optimizely customer success manager.
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.
Initialize Optimizely with a datafile. This datafile will be used as the source of ProjectConfig throughout the life of Optimizely instance:
optimizely.Optimizely(
datafile
)
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'
)
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
)
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.
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.
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 Feature Experimentation documentation to learn how to set up your first Python project and use the SDK.
Build and install the SDK with pip, using the following command:
pip install -e .
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
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
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
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
Please see CONTRIBUTING.
This software incorporates code from the following open source projects:
requests (Apache-2.0 License: https://github.com/psf/requests/blob/master/LICENSE)
idna (BSD 3-Clause License https://github.com/kjd/idna/blob/master/LICENSE.md)
Flutter - https://github.com/optimizely/optimizely-flutter-sdk
JavaScript - https://github.com/optimizely/javascript-sdk
November 27th, 2024
Added support for batch processing in DecideAll and DecideForKeys, enabling more efficient handling of multiple decisions in the User Profile Service.(#440)
June 26th, 2024
We removed redundant dependencies pyOpenSSL and cryptography (#435, #436).
January 18th, 2024
The 5.0.0 release introduces a new primary feature, Advanced Audience Targeting enabled through integration with Optimizely Data Platform (ODP) (#395, #398, #402, #403, #405).
You can use ODP, a high-performance Customer Data Platform (CDP), to easily create complex real-time segments (RTS) using first-party and 50+ third-party data sources out of the box. You can create custom schemas that support the user attributes important for your business, and stitch together user behavior done on different devices to better understand and target your customers for personalized user experiences. ODP can be used as a single source of truth for these segments in any Optimizely or 3rd party tool.
With ODP accounts integrated into Optimizely projects, you can build audiences using segments pre-defined in ODP. The SDK will fetch the segments for given users and make decisions using the segments. For access to ODP audience targeting in your Feature Experimentation account, please contact your Optimizely Customer Success Manager.
This version includes the following changes:
New API added to OptimizelyUserContext
:
fetchQualifiedSegments()
: this API will retrieve user segments from the ODP server. The fetched segments will be used for audience evaluation. The fetched data will be stored in the local cache to avoid repeated network delays.OptimizelyUserContext
is created, the SDK will automatically send an identify request to the ODP server to facilitate observing user activities.New APIs added to OptimizelyClient
:
sendOdpEvent()
: customers can build/send arbitrary ODP events that will bind user identifiers and data to user profiles in ODP.For details, refer to our documentation pages:
py.typed
to enable external usage of mypy type annotations.ODPManager
in the SDK is enabled by default. Unless an ODP account is integrated into the Optimizely projects, most ODPManager
functions will be ignored. If needed, ODPManager
can be disabled when OptimizelyClient
is instantiated.BaseConfigManager
abstract class now requires a get_sdk_key method. (#413)PollingConfigManager
requires either the sdk_key parameter or datafile containing an sdkKey. (#413)BatchEventProcessor
is now the default event processor. (#378)Apr 28th, 2023
The 5.0.0-beta release introduces a new primary feature, Advanced Audience Targeting enabled through integration with Optimizely Data Platform (ODP) (#395, #398, #402, #403, #405).
You can use ODP, a high-performance Customer Data Platform (CDP), to easily create complex real-time segments (RTS) using first-party and 50+ third-party data sources out of the box. You can create custom schemas that support the user attributes important for your business, and stitch together user behavior done on different devices to better understand and target your customers for personalized user experiences. ODP can be used as a single source of truth for these segments in any Optimizely or 3rd party tool.
With ODP accounts integrated into Optimizely projects, you can build audiences using segments pre-defined in ODP. The SDK will fetch the segments for given users and make decisions using the segments. For access to ODP audience targeting in your Feature Experimentation account, please contact your Optimizely Customer Success Manager.
This version includes the following changes:
New API added to OptimizelyUserContext
:
fetchQualifiedSegments()
: this API will retrieve user segments from the ODP server. The fetched segments will be used for audience evaluation. The fetched data will be stored in the local cache to avoid repeated network delays.OptimizelyUserContext
is created, the SDK will automatically send an identify request to the ODP server to facilitate observing user activities.New APIs added to OptimizelyClient
:
sendOdpEvent()
: customers can build/send arbitrary ODP events that will bind user identifiers and data to user profiles in ODP.For details, refer to our documentation pages:
ODPManager
in the SDK is enabled by default. Unless an ODP account is integrated into the Optimizely projects, most ODPManager
functions will be ignored. If needed, ODPManager
can be disabled when OptimizelyClient
is instantiated.BaseConfigManager
abstract class now requires a get_sdk_key method. (#413)PollingConfigManager
requires either the sdk_key parameter or datafile containing an sdkKey. (#413)BatchEventProcessor
is now the default event processor. (#378)March 10th, 2023
We updated our README.md and other non-functional code to reflect that this SDK supports both Optimizely Feature Experimentation and Optimizely Full Stack. (#420)
July 7th, 2022
ProjectConfig.to_datafile
and OptimizelyConfig.get_datafile
(#321, #384)January 12th, 2022
Add a set of new APIs for overriding and managing user-level flag, experiment and delivery rule decisions. These methods can be used for QA and automated testing purposes. They are an extension of the OptimizelyUserContext interface (#361, #365, #369):
For details, refer to our documentation pages: OptimizelyUserContext and Forced Decision methods.
Python v3.4
has been dropped as of this release due to a security vulnerability with PyYAML <v5.4
. (#366)Python v2.7, v3.5, and v3.6
including PyPy
as of this release. (#377)Python v3.7 and above
including PyPy3
.September 16th, 2021
Added new public properties to OptimizelyConfig.
For details please refer to our documentation page:
OptimizelyFeature.experiments_map of OptimizelyConfig is now deprecated. Please use OptimizelyFeature.experiment_rules and OptimizelyFeature.delivery_rules. [#360] (https://github.com/optimizely/python-sdk/pull/360)
July 14th, 2021
June 1st, 2021
February 12th, 2021
New Features
Introducing a new primary interface for retrieving feature flag status, configuration and associated experiment decisions for users (#309). The new OptimizelyUserContext
class is instantiated with create_user_context
and exposes the following APIs to get OptimizelyDecision
:
For details, refer to our documentation page: https://docs.developers.optimizely.com/full-stack/v4.0/docs/python-sdk.
November 19th, 2020
November 2nd, 2020
October 1st, 2020
July 14th, 2020
PollingConfigManager
and AuthDatafilePollingConfigManager
. (#287)July 10th, 2020
PollingConfigManager
. (#285)July 9th, 2020
get_feature_variable_json
allows you to get value for JSON variables related to a feature.get_all_feature_variables
gets values for all variables under a feature.AuthDatafilePollingConfigManager
is a new config manager that allows you to poll for a datafile belonging to a secure environment. You can create a client by setting the datafile_access_token
.June 11th, 2020
March 19th, 2020
jsonschema
to address installation issue.January 27th, 2020
get_optimizely_config()
to get a snapshot of project configuration static data.OptimizelyConfig
instance which includes a datafile revision number, all experiments, and feature flags mapped by their key values.get_optimizely_config()
- OptimizelyConfig
object will be cached and reused for the lifetime of the datafile.December 16th, 2019
October 28th, 2019
activate
, track
, and is_feature_enabled
will be held in a queue until the configured batch size is reached, or the configured flush interval has elapsed. Then, they will be batched into a single payload and sent to the event dispatcher.batch_size
and flush_interval
properties when initializing instance of BatchEventProcessor.BatchEventProcessor
when creating Optimizely
instance to enable event batching.LogEvent
notification to be notified of whenever a payload consisting of a batch of user events is handed off to the event dispatcher to send to Optimizely's backend.PollingConfigManager
. By default, calls to get_config
will block for maximum of 10 seconds until config is available.August 27th, 2019
optimizely.Optimizely
. Based on that, the SDK will use the StaticConfigManager or the PollingConfigManager. Refer to the README for more instructions.PollingConfigManager
to bootstrap before making HTTP requests for the hosted datafile.Optimizely.get_feature_variable
API. (#191)NotificationCenter.clear_notifications
is deprecated as of this release. Please use NotificationCenter.clear_notification_listeners
. (#182)NotificationCenter.clear_all_notifications
is deprecated as of this release. Please use NotificationCenter.clear_all_notification_listeners
. (#182)July 26th, 2019
optimizely.Optimizely
. Based on that, the SDK will use the StaticConfigManager or the PollingConfigManager. Refer to the README for more instructions.PollingConfigManager
to bootstrap before making HTTP requests for the hosted datafile.Optimizely.get_feature_variable
API. (#191)NotificationCenter.clear_notifications
is deprecated as of this release. Please use NotificationCenter.clear_notification_listeners
. (#182)NotificationCenter.clear_all_notifications
is deprecated as of this release. Please use NotificationCenter.clear_all_notification_listeners
. (#182)May 3rd, 2019
March 1st, 2019
The 3.0 release improves event tracking and supports additional audience targeting functionality.
track
method now dispatches its conversion event unconditionally, without first determining whether the user is targeted by a known experiment that uses the event. This may increase outbound network traffic.exists
matcher that passes if the user has a non-null value for the targeted user attribute and fails otherwise.substring
matcher that resolves if the user has a string value for the targeted attribute.
gt
(greater than) and lt
(less than) matchers that resolve if the user has a valid number value for the targeted attribute. A valid number is a finite float or numbers.Integral in the inclusive range [-2 ^ 53, 2 ^ 53].exact
) matcher can now be used to target booleans and valid numbers, not just strings."and"
and "not"
operators, not just the "or"
operator.exists
matcher) no longer resolve to false
when they fail to find an legitimate value for the targeted user attribute. The result remains null
(unknown). Therefore, an audience that negates such a condition (using the "not"
operator) can no longer resolve to true
unless there is an unrelated branch in the condition tree that itself resolves to true
.August 21st, 2018
July 2nd, 2018
June 19th, 2018
April 12th, 2018
This major release introduces APIs for Feature Management. It also introduces some breaking changes listed below.
is_feature_enabled
API to determine whether to show a feature to a user or not. is_enabled = optimizel_client.is_feature_enabled('my_feature_key', 'my_user', user_attributes)
enabled_features = optimizely_client.get_enabled_features('my_user', user_attributes)
String
, Integer
, Double
, Boolean
. string_variable = optimizely_client.get_feature_variable_string('my_feature_key', 'string_variable_key', 'my_user')
integer_variable = optimizely_client.get_feature_variable_integer('my_feature_key', 'integer_variable_key', 'my_user')
double_variable = optimizely_client.get_feature_variable_double('my_feature_key', 'double_variable_key', 'my_user')
boolean_variable = optimizely_client.get_feature_variable_boolean('my_feature_key', 'boolean_variable_key', 'my_user')
track
API with revenue value as a stand-alone parameter has been removed. The revenue value should be passed in as an entry in the event tags dict. The key for the revenue tag is revenue
and the passed in value will be treated by Optimizely as the value for computing results. event_tags = {
'revenue': 1200
}
optimizely_client.track('event_key', 'my_user', user_attributes, event_tags)
March 29th, 2018
This beta release introduces APIs for Feature Management. It also introduces some breaking changes listed below.
is_feature_enabled
API to determine whether to show a feature to a user or not. is_enabled = optimizel_client.is_feature_enabled('my_feature_key', 'my_user', user_attributes)
enabled_features = optimizely_client.get_enabled_features('my_user', user_attributes)
String
, Integer
, Double
, Boolean
. string_variable = optimizely_client.get_feature_variable_string('my_feature_key', 'string_variable_key', 'my_user')
integer_variable = optimizely_client.get_feature_variable_integer('my_feature_key', 'integer_variable_key', 'my_user')
double_variable = optimizely_client.get_feature_variable_double('my_feature_key', 'double_variable_key', 'my_user')
boolean_variable = optimizely_client.get_feature_variable_boolean('my_feature_key', 'boolean_variable_key', 'my_user')
track
API with revenue value as a stand-alone parameter has been removed. The revenue value should be passed in as an entry in the event tags dict. The key for the revenue tag is revenue
and the passed in value will be treated by Optimizely as the value for computing results. event_tags = {
'revenue': 1200
}
optimizely_client.track('event_key', 'my_user', user_attributes, event_tags)
event_value
parameter from the track method. Should use event_tags
to pass in event value instead.FAQs
Python SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts.
We found that optimizely-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.