Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
35a6eac
add user context
thomaszurkan-optimizely Nov 9, 2020
509ff50
cleanup lint
thomaszurkan-optimizely Nov 9, 2020
0ef34ee
update comments
thomaszurkan-optimizely Nov 9, 2020
61fe356
fixes from ali's comments
thomaszurkan-optimizely Nov 25, 2020
c8cabbd
add all decide objects
thomaszurkan-optimizely Nov 25, 2020
dc226c1
add decide apis
thomaszurkan-optimizely Nov 26, 2020
366030e
Merge branch 'master' into decideApi
thomaszurkan-optimizely Nov 26, 2020
fd99ec1
fix lint errors
thomaszurkan-optimizely Nov 26, 2020
36b0328
Merge branch 'decideApi' of https://github.com/optimizely/python-sdk …
thomaszurkan-optimizely Nov 26, 2020
19b7fae
added unit tests and cleanup decide
thomaszurkan-optimizely Dec 3, 2020
ffa40d6
cleanup lint errors
thomaszurkan-optimizely Dec 3, 2020
13ec677
fix lint
thomaszurkan-optimizely Dec 3, 2020
5feca2c
remove reduce to work with python 3.x
thomaszurkan-optimizely Dec 3, 2020
4c4b4a4
add more unit tests for user context
thomaszurkan-optimizely Dec 3, 2020
460c904
another test
thomaszurkan-optimizely Dec 3, 2020
0d4ec50
try and fix travis pypy tests
thomaszurkan-optimizely Dec 3, 2020
8b5d56d
attempt to fix pypy on travis
thomaszurkan-optimizely Dec 3, 2020
a1cbc68
fix travis pypy
thomaszurkan-optimizely Dec 3, 2020
67fc4f2
add more tests
thomaszurkan-optimizely Dec 8, 2020
f3e3854
finish python with reasons
thomaszurkan-optimizely Dec 9, 2020
c38dbfc
make sure we are at the lowest level DEBUG
thomaszurkan-optimizely Dec 9, 2020
2c1f8b0
only capture info messages and up
thomaszurkan-optimizely Dec 10, 2020
9517442
refact: Decide API (#314)
oakbani Feb 1, 2021
4f00cb5
Merge branch 'master' into decideApi
jaeopt Feb 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ python:
# - "3.8" is handled in 'Test' job using xenial as Python 3.8 is not available for trusty.
- "pypy"
- "pypy3"
before_install:
- sudo apt-get --auto-remove --yes remove python-openssl
- sudo pip install pyOpenSSL
install: "pip install -r requirements/core.txt;pip install -r requirements/test.txt"
script: "pytest --cov=optimizely"
after_success:
Expand Down
12 changes: 12 additions & 0 deletions optimizely/decision/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2020, Optimizely
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
20 changes: 20 additions & 0 deletions optimizely/decision/decide_option.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2020, Optimizely
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


class DecideOption(object):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change the name to "OptimizelyDecideOption"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is not consistent with the rest of the sdk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 314

DISABLE_DECISION_EVENT = 'DISABLE_DECISION_EVENT'
ENABLED_FLAGS_ONLY = 'ENABLED_FLAGS_ONLY'
IGNORE_USER_PROFILE_SERVICE = 'IGNORE_USER_PROFILE_SERVICE'
INCLUDE_REASONS = 'INCLUDE_REASONS'
EXCLUDE_VARIABLES = 'EXCLUDE_VARIABLES'
24 changes: 24 additions & 0 deletions optimizely/decision/decision.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2020, Optimizely
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


class Decision(object):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change the name to "OptimizelyDecision"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 314

def __init__(self, variation_key=None, enabled=None,
variables=None, rule_key=None, flag_key=None, user_context=None, reasons=None):
self.variation_key = variation_key
self.enabled = enabled or False
self.variables = variables or {}
self.rule_key = rule_key
self.flag_key = flag_key
self.user_context = user_context
self.reasons = reasons or []
18 changes: 18 additions & 0 deletions optimizely/decision/decision_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2020, Optimizely
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


class DecisionMessage(object):
SDK_NOT_READY = 'Optimizely SDK not configured properly yet.'
FLAG_KEY_INVALID = 'No flag was found for key "%s".'
VARIABLE_VALUE_INVALID = 'Variable value for key "%s" is invalid or wrong type.'
8 changes: 5 additions & 3 deletions optimizely/decision_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ def get_variation_for_rollout(self, project_config, rollout, user_id, attributes
rollout: Rollout for which we are getting the variation.
user_id: ID for user.
attributes: Dict representing user attributes.
ignore_user_profile: True if we should bypass the user profile service

Returns:
Decision namedtuple consisting of experiment and variation for the user.
Expand Down Expand Up @@ -390,14 +391,15 @@ def get_experiment_in_group(self, project_config, group, bucketing_id):

return None

def get_variation_for_feature(self, project_config, feature, user_id, attributes=None):
def get_variation_for_feature(self, project_config, feature, user_id, attributes=None, ignore_user_profile=False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's interesting - I see that python-sdk already has "ignore_user_profile" option. We can keep the current structure to reuse it, but I'm concerned we may need to add options to support other options later.

""" Returns the experiment/variation the user is bucketed in for the given feature.

Args:
project_config: Instance of ProjectConfig.
feature: Feature for which we are determining if it is enabled or not for the given user.
user_id: ID for user.
attributes: Dict representing user attributes.
ignore_user_profile: True if you want to bypass the user profile service

Returns:
Decision namedtuple consisting of experiment and variation for the user.
Expand All @@ -411,7 +413,7 @@ def get_variation_for_feature(self, project_config, feature, user_id, attributes
if group:
experiment = self.get_experiment_in_group(project_config, group, bucketing_id)
if experiment and experiment.id in feature.experimentIds:
variation = self.get_variation(project_config, experiment, user_id, attributes)
variation = self.get_variation(project_config, experiment, user_id, attributes, ignore_user_profile)

if variation:
return Decision(experiment, variation, enums.DecisionSources.FEATURE_TEST)
Expand All @@ -423,7 +425,7 @@ def get_variation_for_feature(self, project_config, feature, user_id, attributes
# If an experiment is not in a group, then the feature can only be associated with one experiment
experiment = project_config.get_experiment_from_id(feature.experimentIds[0])
if experiment:
variation = self.get_variation(project_config, experiment, user_id, attributes)
variation = self.get_variation(project_config, experiment, user_id, attributes, ignore_user_profile)

if variation:
return Decision(experiment, variation, enums.DecisionSources.FEATURE_TEST)
Expand Down
Loading