Skip to content

Commit 4cbf7c5

Browse files
mauerbacaliabbasrizvi
authored andcommitted
Implement IP Anonymization (#87)
1 parent c2a8349 commit 4cbf7c5

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

optimizely/event_builder.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class EventParams(object):
124124
SOURCE_SDK_TYPE = 'client_name'
125125
SOURCE_SDK_VERSION = 'client_version'
126126
CUSTOM = 'custom'
127+
ANONYMIZE_IP = 'anonymize_ip'
127128

128129
def _add_attributes(self, attributes):
129130
""" Add attribute(s) information to the event.
@@ -172,6 +173,11 @@ def _add_visitor(self, user_id):
172173
visitor[self.EventParams.SNAPSHOTS] = []
173174
self.params[self.EventParams.USERS].append(visitor)
174175

176+
def _add_anonymize_ip(self):
177+
""" Add IP anonymization bool to the event """
178+
179+
self.params[self.EventParams.ANONYMIZE_IP] = self.config.get_anonymize_ip_value()
180+
175181
def _add_common_params(self, user_id, attributes):
176182
""" Add params which are used same in both conversion and impression events.
177183
@@ -184,6 +190,7 @@ def _add_common_params(self, user_id, attributes):
184190
self._add_visitor(user_id)
185191
self._add_attributes(attributes)
186192
self._add_source()
193+
self._add_anonymize_ip()
187194

188195
def _add_required_params_for_impression(self, experiment, variation_id):
189196
""" Add parameters that are required for the impression event to register.

optimizely/project_config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def __init__(self, datafile, logger, error_handler):
5555
self.audiences = config.get('audiences', [])
5656
self.feature_flags = config.get('featureFlags', [])
5757
self.rollouts = config.get('rollouts', [])
58+
self.anonymize_ip = config.get('anonymizeIP', False)
5859

5960
# Utility maps for quick lookup
6061
self.group_id_map = self._generate_key_map(self.groups, 'id', entities.Group)
@@ -566,3 +567,12 @@ def get_forced_variation(self, experiment_key, user_id):
566567
'Variation "%s" is mapped to experiment "%s" and user "%s" in the forced variation map'
567568
% (variation.key, experiment_key, user_id))
568569
return variation
570+
571+
def get_anonymize_ip_value(self):
572+
""" Gets the anonymize IP value.
573+
574+
Returns:
575+
A boolean value that indicates if the IP should be anonymized.
576+
"""
577+
578+
return self.anonymize_ip

tests/test_event_builder.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ def test_create_impression_event(self):
7878
}]
7979
}],
8080
'client_name': 'python-sdk',
81-
'client_version': version.__version__
81+
'client_version': version.__version__,
82+
'anonymize_ip': False,
8283
}
8384

8485
with mock.patch('time.time', return_value=42.123), \
@@ -122,7 +123,8 @@ def test_create_impression_event__with_attributes(self):
122123
}]
123124
}],
124125
'client_name': 'python-sdk',
125-
'client_version': version.__version__
126+
'client_version': version.__version__,
127+
'anonymize_ip': False
126128
}
127129

128130
with mock.patch('time.time', return_value=42.123), \
@@ -167,7 +169,8 @@ def test_create_conversion_event__with_attributes(self):
167169
}]
168170
}],
169171
'client_name': 'python-sdk',
170-
'client_version': version.__version__
172+
'client_version': version.__version__,
173+
'anonymize_ip': False
171174
}
172175

173176
with mock.patch('time.time', return_value=42.123), \
@@ -220,6 +223,7 @@ def test_create_conversion_event__with_event_tags(self):
220223
}],
221224
'account_id': '12001',
222225
'client_name': 'python-sdk',
226+
'anonymize_ip': False
223227
}
224228

225229
with mock.patch('time.time', return_value=42.123), \
@@ -274,6 +278,7 @@ def test_create_conversion_event__with_invalid_event_tags(self):
274278
}],
275279
'account_id': '12001',
276280
'client_name': 'python-sdk',
281+
'anonymize_ip': False
277282
}
278283

279284
with mock.patch('time.time', return_value=42.123), \

tests/test_optimizely.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ def test_activate(self):
161161
}]
162162
}],
163163
'client_version': version.__version__,
164-
'client_name': 'python-sdk'
164+
'client_name': 'python-sdk',
165+
'anonymize_ip': False
165166
}
166167
mock_decision.assert_called_once_with(
167168
self.project_config.get_experiment_from_key('test_experiment'), 'test_user', None
@@ -209,7 +210,8 @@ def test_activate__with_attributes__audience_match(self):
209210
}]
210211
}],
211212
'client_version': version.__version__,
212-
'client_name': 'python-sdk'
213+
'client_name': 'python-sdk',
214+
'anonymize_ip': False
213215
}
214216
mock_get_variation.assert_called_once_with(self.project_config.get_experiment_from_key('test_experiment'),
215217
'test_user', {'test_attribute': 'test_value'})
@@ -256,7 +258,8 @@ def test_activate__with_attributes__audience_match__forced_bucketing(self):
256258
}]
257259
}],
258260
'client_version': version.__version__,
259-
'client_name': 'python-sdk'
261+
'client_name': 'python-sdk',
262+
'anonymize_ip': False
260263
}
261264

262265
self.assertEqual(1, mock_dispatch_event.call_count)
@@ -368,7 +371,8 @@ def test_track__with_attributes(self):
368371
}]
369372
}],
370373
'client_version': version.__version__,
371-
'client_name': 'python-sdk'
374+
'client_name': 'python-sdk',
375+
'anonymize_ip': False
372376
}
373377
mock_get_variation.assert_called_once_with(self.project_config.get_experiment_from_key('test_experiment'),
374378
'test_user', {'test_attribute': 'test_value'})
@@ -446,7 +450,8 @@ def test_track__with_event_tags(self):
446450
}],
447451
}],
448452
'client_version': version.__version__,
449-
'client_name': 'python-sdk'
453+
'client_name': 'python-sdk',
454+
'anonymize_ip': False
450455
}
451456
mock_get_variation.assert_called_once_with(self.project_config.get_experiment_from_key('test_experiment'),
452457
'test_user', {'test_attribute': 'test_value'})
@@ -499,7 +504,8 @@ def test_track__with_event_tags_revenue(self):
499504
'client_name': 'python-sdk',
500505
'project_id': '111001',
501506
'client_version': version.__version__,
502-
'account_id': '12001'
507+
'account_id': '12001',
508+
'anonymize_ip': False
503509
}
504510
mock_get_variation.assert_called_once_with(self.project_config.get_experiment_from_key('test_experiment'),
505511
'test_user', {'test_attribute': 'test_value'})
@@ -583,7 +589,8 @@ def test_track__with_event_tags__forced_bucketing(self):
583589
}],
584590
}],
585591
'client_version': version.__version__,
586-
'client_name': 'python-sdk'
592+
'client_name': 'python-sdk',
593+
'anonymize_ip': False
587594
}
588595

589596
self.assertEqual(1, mock_dispatch_event.call_count)
@@ -633,7 +640,8 @@ def test_track__with_deprecated_event_value(self):
633640
}],
634641
}],
635642
'client_version': version.__version__,
636-
'client_name': 'python-sdk'
643+
'client_name': 'python-sdk',
644+
'anonymize_ip': False
637645
}
638646
mock_get_variation.assert_called_once_with(self.project_config.get_experiment_from_key('test_experiment'),
639647
'test_user', {'test_attribute': 'test_value'})
@@ -684,7 +692,8 @@ def test_track__with_invalid_event_tags(self):
684692
'client_name': 'python-sdk',
685693
'project_id': '111001',
686694
'client_version': version.__version__,
687-
'account_id': '12001'
695+
'account_id': '12001',
696+
'anonymize_ip': False
688697
}
689698
mock_get_variation.assert_called_once_with(self.project_config.get_experiment_from_key('test_experiment'),
690699
'test_user', {'test_attribute': 'test_value'})
@@ -798,7 +807,8 @@ def test_is_feature_enabled__returns_true_if_user_is_bucketed_into_a_variation_o
798807
}]
799808
}],
800809
'client_version': version.__version__,
801-
'client_name': 'python-sdk'
810+
'client_name': 'python-sdk',
811+
'anonymize_ip': False,
802812
}
803813
# Check that impression event is sent
804814
self.assertEqual(1, mock_dispatch_event.call_count)

0 commit comments

Comments
 (0)