Skip to content

Commit

Permalink
Merge a7039a4 into 8562eee
Browse files Browse the repository at this point in the history
  • Loading branch information
aliabbasrizvi authored Jun 10, 2020
2 parents 8562eee + a7039a4 commit 0585607
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 28 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# Optimizely Python SDK Changelog

## 3.4.2
June 11th, 2020

### Bug Fixes:
* Adjusted log level for audience evaluation logs. ([#267](https://github.com/optimizely/python-sdk/pull/267))

## 3.4.1
March 19th, 2020

### Bug Fixes:
* Updated `jsonschema` to address [installation issue](https://github.com/optimizely/python-sdk/issues/232).


## 3.4.0
January 27th, 2020

Expand Down
4 changes: 2 additions & 2 deletions optimizely/entities.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016-2018, Optimizely
# Copyright 2016-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
Expand Down Expand Up @@ -67,7 +67,7 @@ def __init__(
self.groupId = groupId
self.groupPolicy = groupPolicy

def getAudienceConditionsOrIds(self):
def get_audience_conditions_or_ids(self):
""" Returns audienceConditions if present, otherwise audienceIds. """
return self.audienceConditions if self.audienceConditions is not None else self.audienceIds

Expand Down
22 changes: 9 additions & 13 deletions optimizely/helpers/audience.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016, 2018-2019, Optimizely
# Copyright 2016, 2018-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
Expand Down Expand Up @@ -32,8 +32,7 @@ def is_user_in_experiment(config, experiment, attributes, logger):
Boolean representing if user satisfies audience conditions for any of the audiences or not.
"""

audience_conditions = experiment.getAudienceConditionsOrIds()

audience_conditions = experiment.get_audience_conditions_or_ids()
logger.debug(audience_logs.EVALUATING_AUDIENCES_COMBINED.format(experiment.key, json.dumps(audience_conditions)))

# Return True in case there are no audiences
Expand All @@ -45,35 +44,32 @@ def is_user_in_experiment(config, experiment, attributes, logger):
if attributes is None:
attributes = {}

def evaluate_custom_attr(audienceId, index):
audience = config.get_audience(audienceId)
def evaluate_custom_attr(audience_id, index):
audience = config.get_audience(audience_id)
custom_attr_condition_evaluator = condition_helper.CustomAttributeConditionEvaluator(
audience.conditionList, attributes, logger
)

return custom_attr_condition_evaluator.evaluate(index)

def evaluate_audience(audienceId):
audience = config.get_audience(audienceId)
def evaluate_audience(audience_id):
audience = config.get_audience(audience_id)

if audience is None:
return None

logger.debug(audience_logs.EVALUATING_AUDIENCE.format(audienceId, audience.conditions))
logger.debug(audience_logs.EVALUATING_AUDIENCE.format(audience_id, audience.conditions))

result = condition_tree_evaluator.evaluate(
audience.conditionStructure, lambda index: evaluate_custom_attr(audienceId, index),
audience.conditionStructure, lambda index: evaluate_custom_attr(audience_id, index),
)

result_str = str(result).upper() if result is not None else 'UNKNOWN'
logger.info(audience_logs.AUDIENCE_EVALUATION_RESULT.format(audienceId, result_str))
logger.debug(audience_logs.AUDIENCE_EVALUATION_RESULT.format(audience_id, result_str))

return result

eval_result = condition_tree_evaluator.evaluate(audience_conditions, evaluate_audience)

eval_result = eval_result or False

logger.info(audience_logs.AUDIENCE_EVALUATION_RESULT_COMBINED.format(experiment.key, str(eval_result).upper()))

return eval_result
24 changes: 12 additions & 12 deletions tests/helpers_tests/test_audience.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016-2019, Optimizely
# Copyright 2016-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
Expand Down Expand Up @@ -140,7 +140,7 @@ def test_is_user_in_experiment__returns_False__when_condition_tree_evaluator_ret
)
)

def test_is_user_in_experiment__evaluates_audienceIds(self):
def test_is_user_in_experiment__evaluates_audience_ids(self):
""" Test that is_user_in_experiment correctly evaluates audience Ids and
calls custom attribute evaluator for leaf nodes. """

Expand Down Expand Up @@ -241,7 +241,7 @@ def test_is_user_in_experiment__with_no_audience(self):
]
)

def test_is_user_in_experiment__evaluates_audienceIds(self):
def test_is_user_in_experiment__evaluates_audience_ids(self):
user_attributes = {'test_attribute': 'test_value_1'}
experiment = self.project_config.get_experiment_from_key('test_experiment')
experiment.audienceIds = ['11154', '11159']
Expand All @@ -256,20 +256,20 @@ def test_is_user_in_experiment__evaluates_audienceIds(self):
self.project_config, experiment, user_attributes, self.mock_client_logger,
)

self.assertEqual(3, self.mock_client_logger.debug.call_count)
self.assertEqual(3, self.mock_client_logger.info.call_count)
self.assertEqual(5, self.mock_client_logger.debug.call_count)
self.assertEqual(1, self.mock_client_logger.info.call_count)

self.mock_client_logger.assert_has_calls(
[
mock.call.debug('Evaluating audiences for experiment "test_experiment": ["11154", "11159"].'),
mock.call.debug(
'Starting to evaluate audience "11154" with conditions: ' + audience_11154.conditions + '.'
),
mock.call.info('Audience "11154" evaluated to UNKNOWN.'),
mock.call.debug('Audience "11154" evaluated to UNKNOWN.'),
mock.call.debug(
'Starting to evaluate audience "11159" with conditions: ' + audience_11159.conditions + '.'
),
mock.call.info('Audience "11159" evaluated to UNKNOWN.'),
mock.call.debug('Audience "11159" evaluated to UNKNOWN.'),
mock.call.info('Audiences for experiment "test_experiment" collectively evaluated to FALSE.'),
]
)
Expand All @@ -292,8 +292,8 @@ def test_is_user_in_experiment__evaluates_audience_conditions(self):
):
audience.is_user_in_experiment(project_config, experiment, {}, self.mock_client_logger)

self.assertEqual(4, self.mock_client_logger.debug.call_count)
self.assertEqual(4, self.mock_client_logger.info.call_count)
self.assertEqual(7, self.mock_client_logger.debug.call_count)
self.assertEqual(1, self.mock_client_logger.info.call_count)

self.mock_client_logger.assert_has_calls(
[
Expand All @@ -306,17 +306,17 @@ def test_is_user_in_experiment__evaluates_audience_conditions(self):
'Starting to evaluate audience "3468206642" with '
'conditions: ' + audience_3468206642.conditions + '.'
),
mock.call.info('Audience "3468206642" evaluated to FALSE.'),
mock.call.debug('Audience "3468206642" evaluated to FALSE.'),
mock.call.debug(
'Starting to evaluate audience "3988293898" with '
'conditions: ' + audience_3988293898.conditions + '.'
),
mock.call.info('Audience "3988293898" evaluated to UNKNOWN.'),
mock.call.debug('Audience "3988293898" evaluated to UNKNOWN.'),
mock.call.debug(
'Starting to evaluate audience "3988293899" with '
'conditions: ' + audience_3988293899.conditions + '.'
),
mock.call.info('Audience "3988293899" evaluated to TRUE.'),
mock.call.debug('Audience "3988293899" evaluated to TRUE.'),
mock.call.info(
'Audiences for experiment "audience_combinations_experiment" collectively evaluated to TRUE.'
),
Expand Down

0 comments on commit 0585607

Please sign in to comment.