From d9e8f83dbb5f0734de5ab98959d0334b230b250a Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 15:25:28 +0400 Subject: [PATCH 01/25] [FSSDK-11458] Python - Add SDK Multi-Region Support for Data Hosting --- optimizely/event/event_factory.py | 10 ++- optimizely/event/user_event.py | 4 +- optimizely/event/user_event_factory.py | 4 +- optimizely/event_builder.py | 16 ++++- optimizely/project_config.py | 7 ++- tests/test_config.py | 27 ++++++++- tests/test_optimizely.py | 84 ++++++++++++++++++++++++++ tests/test_user_event_factory.py | 17 ++++++ 8 files changed, 158 insertions(+), 11 deletions(-) diff --git a/optimizely/event/event_factory.py b/optimizely/event/event_factory.py index 8a4bb0cf8..3dbbb8163 100644 --- a/optimizely/event/event_factory.py +++ b/optimizely/event/event_factory.py @@ -42,7 +42,10 @@ class EventFactory: to record the events via the Optimizely Events API ("https://developers.optimizely.com/x/events/api/index.html") """ - EVENT_ENDPOINT: Final = 'https://logx.optimizely.com/v1/events' + EVENT_ENDPOINTS: Final = { + 'US': 'https://logx.optimizely.com/v1/events', + 'EU': 'https://eu.logx.optimizely.com/v1/events' + } HTTP_VERB: Final = 'POST' HTTP_HEADERS: Final = {'Content-Type': 'application/json'} ACTIVATE_EVENT_KEY: Final = 'campaign_activated' @@ -97,7 +100,10 @@ def create_log_event( event_params = event_batch.get_event_params() - return log_event.LogEvent(cls.EVENT_ENDPOINT, event_params, cls.HTTP_VERB, cls.HTTP_HEADERS) + region = user_context.region or 'US' + endpoint = cls.EVENT_ENDPOINTS.get(region) + + return log_event.LogEvent(endpoint, event_params, cls.HTTP_VERB, cls.HTTP_HEADERS) @classmethod def _create_visitor(cls, event: Optional[user_event.UserEvent], logger: Logger) -> Optional[payload.Visitor]: diff --git a/optimizely/event/user_event.py b/optimizely/event/user_event.py index 9cdb623a9..243234d3b 100644 --- a/optimizely/event/user_event.py +++ b/optimizely/event/user_event.py @@ -17,6 +17,7 @@ from sys import version_info from optimizely import version +from optimizely.project_config import Region if version_info < (3, 8): @@ -97,10 +98,11 @@ def __init__( class EventContext: """ Class respresenting User Event Context. """ - def __init__(self, account_id: str, project_id: str, revision: str, anonymize_ip: bool): + def __init__(self, account_id: str, project_id: str, revision: str, anonymize_ip: bool, region: Region): self.account_id = account_id self.project_id = project_id self.revision = revision self.client_name = CLIENT_NAME self.client_version = version.__version__ self.anonymize_ip = anonymize_ip + self.region = region or 'US' diff --git a/optimizely/event/user_event_factory.py b/optimizely/event/user_event_factory.py index ef07d06be..cd2791558 100644 --- a/optimizely/event/user_event_factory.py +++ b/optimizely/event/user_event_factory.py @@ -76,7 +76,7 @@ def create_impression_event( variation = project_config.get_variation_from_id_by_experiment_id(experiment_id, variation_id) event_context = user_event.EventContext( - project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, + project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, project_config.region ) return user_event.ImpressionEvent( @@ -115,7 +115,7 @@ def create_conversion_event( """ event_context = user_event.EventContext( - project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, + project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, project_config.region ) return user_event.ConversionEvent( diff --git a/optimizely/event_builder.py b/optimizely/event_builder.py index ecabf14c1..a243b94d3 100644 --- a/optimizely/event_builder.py +++ b/optimizely/event_builder.py @@ -54,7 +54,10 @@ class EventBuilder: """ Class which encapsulates methods to build events for tracking impressions and conversions using the new V3 event API (batch). """ - EVENTS_URL: Final = 'https://logx.optimizely.com/v1/events' + EVENTS_URLS: Final = { + 'US': 'https://logx.optimizely.com/v1/events', + 'EU': 'https://eu.logx.optimizely.com/v1/events' + } HTTP_VERB: Final = 'POST' HTTP_HEADERS: Final = {'Content-Type': 'application/json'} @@ -266,7 +269,10 @@ def create_impression_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(impression_params) - return Event(self.EVENTS_URL, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) + region = project_config.region or 'US' + events_url = self.EVENTS_URLS.get(region) + + return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) def create_conversion_event( self, project_config: ProjectConfig, event_key: str, @@ -289,4 +295,8 @@ def create_conversion_event( conversion_params = self._get_required_params_for_conversion(project_config, event_key, event_tags) params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params) - return Event(self.EVENTS_URL, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) + + region = project_config.region or 'US' + events_url = self.EVENTS_URLS.get(region) + + return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index f774ff8a6..d13b28dd0 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -22,9 +22,9 @@ from .helpers import types if version_info < (3, 8): - from typing_extensions import Final + from typing_extensions import Final, Literal else: - from typing import Final # type: ignore + from typing import Final, Literal # type: ignore if TYPE_CHECKING: # prevent circular dependenacy by skipping import at runtime @@ -41,6 +41,8 @@ EntityClass = TypeVar('EntityClass') +Region = Literal['US', 'EU'] + class ProjectConfig: """ Representation of the Optimizely project config. """ @@ -84,6 +86,7 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any): self.public_key_for_odp: Optional[str] = None self.host_for_odp: Optional[str] = None self.all_segments: list[str] = [] + self.region: Region = config.get('region') or 'US' # Utility maps for quick lookup self.group_id_map: dict[str, entities.Group] = self._generate_key_map(self.groups, 'id', entities.Group) diff --git a/tests/test_config.py b/tests/test_config.py index 9ec5c7614..265b69044 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -21,7 +21,7 @@ from optimizely import logger from optimizely import optimizely from optimizely.helpers import enums -from optimizely.project_config import ProjectConfig +from optimizely.project_config import ProjectConfig, Region from . import base @@ -154,6 +154,31 @@ def test_init(self): self.assertEqual(expected_variation_key_map, self.project_config.variation_key_map) self.assertEqual(expected_variation_id_map, self.project_config.variation_id_map) + def test_region_when_no_region(self): + """ Test that region defaults to 'US' when not specified in the config. """ + config_dict = copy.deepcopy(self.config_dict_with_multiple_experiments) + opt_obj = optimizely.Optimizely(json.dumps(config_dict)) + project_config = opt_obj.config_manager.get_config() + self.assertEqual(project_config.region, Region.US) + + + def test_region_when_specified_in_datafile(self): + """ Test that region is set to 'US' when specified in the config. """ + config_dict_us = copy.deepcopy(self.config_dict_with_multiple_experiments) + config_dict_us['region'] = 'US' + opt_obj_us = optimizely.Optimizely(json.dumps(config_dict_us)) + project_config_us = opt_obj_us.config_manager.get_config() + self.assertEqual(project_config_us.region, Region.US) + + """ Test that region is set to 'EU' when specified in the config. """ + config_dict_eu = copy.deepcopy(self.config_dict_with_multiple_experiments) + config_dict_eu['region'] = 'EU' + opt_obj_eu = optimizely.Optimizely(json.dumps(config_dict_eu)) + project_config_eu = opt_obj_eu.config_manager.get_config() + self.assertEqual(project_config_eu.region, Region.EU) + + + def test_cmab_field_population(self): """ Test that the cmab field is populated correctly in experiments.""" diff --git a/tests/test_optimizely.py b/tests/test_optimizely.py index 1f4293cdd..2c9caa874 100644 --- a/tests/test_optimizely.py +++ b/tests/test_optimizely.py @@ -365,6 +365,7 @@ def test_activate(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -385,6 +386,76 @@ def test_activate(self): {'Content-Type': 'application/json'}, ) + def test_activate_with_eu_hosting(self): + """ Test that activate calls process with right params and returns expected variation. """ + """ Test EU hosting for activate method. """ + + with mock.patch( + 'optimizely.decision_service.DecisionService.get_variation', + return_value=(self.project_config.get_variation_from_id('test_experiment', '111129'), []), + ) as mock_decision, mock.patch('time.time', return_value=42), mock.patch( + 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' + ), mock.patch( + 'optimizely.event.event_processor.BatchEventProcessor.process' + ) as mock_process: + self.assertEqual('variation', self.optimizely.activate('test_experiment', 'test_user')) + + expected_params = { + 'account_id': '12001', + 'project_id': '111001', + 'visitors': [ + { + 'visitor_id': 'test_user', + 'attributes': [], + 'snapshots': [ + { + 'decisions': [ + {'variation_id': '111129', 'experiment_id': '111127', 'campaign_id': '111182', + 'metadata': {'flag_key': '', + 'rule_key': 'test_experiment', + 'rule_type': 'experiment', + 'variation_key': 'variation', + 'enabled': True}, + } + ], + 'events': [ + { + 'timestamp': 42000, + 'entity_id': '111182', + 'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c', + 'key': 'campaign_activated', + } + ], + } + ], + } + ], + 'client_version': version.__version__, + 'client_name': 'python-sdk', + 'enrich_decisions': True, + 'anonymize_ip': False, + 'revision': '42', + 'region': 'EU', + } + + log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) + user_context = mock_decision.call_args[0][2] + user_profile_tracker = mock_decision.call_args[0][3] + + mock_decision.assert_called_once_with( + self.project_config, self.project_config.get_experiment_from_key('test_experiment'), + user_context, user_profile_tracker + ) + self.assertEqual(1, mock_process.call_count) + + self._validate_event_object( + log_event.__dict__, + 'https://eu.logx.optimizely.com/v1/events', + expected_params, + 'POST', + {'Content-Type': 'application/json'}, + ) + def test_add_activate_remove_clear_listener(self): callbackhit = [False] """ Test adding a listener activate passes correctly and gets called""" @@ -764,6 +835,7 @@ def test_activate__with_attributes__audience_match(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -848,6 +920,7 @@ def test_activate__with_attributes_of_different_types(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1044,6 +1117,7 @@ def test_activate__with_attributes__audience_match__forced_bucketing(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1120,6 +1194,7 @@ def test_activate__with_attributes__audience_match__bucketing_id_provided(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1288,6 +1363,7 @@ def test_track__with_attributes(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1424,6 +1500,7 @@ def test_track__with_attributes__bucketing_id_provided(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1504,6 +1581,7 @@ def test_track__with_event_tags(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1560,6 +1638,7 @@ def test_track__with_event_tags_revenue(self): 'account_id': '12001', 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1648,6 +1727,7 @@ def test_track__with_event_tags__forced_bucketing(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -1703,6 +1783,7 @@ def test_track__with_invalid_event_tags(self): 'account_id': '12001', 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -2103,6 +2184,7 @@ def test_is_feature_enabled__returns_true_for_feature_experiment_if_feature_enab 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '1', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -2204,6 +2286,7 @@ def test_is_feature_enabled__returns_false_for_feature_experiment_if_feature_dis 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '1', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) @@ -2356,6 +2439,7 @@ def test_is_feature_enabled__returns_true_for_feature_rollout_if_feature_enabled 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '1', + 'region': 'US', } log_event = EventFactory.create_log_event(mock_process.call_args[0][0], self.optimizely.logger) diff --git a/tests/test_user_event_factory.py b/tests/test_user_event_factory.py index 009ef05dd..f5bb2f8ea 100644 --- a/tests/test_user_event_factory.py +++ b/tests/test_user_event_factory.py @@ -41,6 +41,20 @@ def test_impression_event(self): self.assertEqual(experiment, impression_event.experiment) self.assertEqual(variation, impression_event.variation) self.assertEqual(user_id, impression_event.user_id) + self.assertEqual(self.project_config.region, impression_event.event_context.region) + + def test_impression_event_with_region_eu(self): + project_config = self.project_config + experiment = self.project_config.get_experiment_from_key('test_experiment') + user_id = 'test_user' + + impression_event = UserEventFactory.create_impression_event( + project_config, experiment, '111128', '', 'rule_key', 'rule_type', True, user_id, None, region='EU' + ) + + self.assertEqual(self.project_config.region, impression_event.event_context.region) + self.assertEqual('EU', impression_event.event_context.region) + def test_impression_event__with_attributes(self): project_config = self.project_config @@ -66,6 +80,7 @@ def test_impression_event__with_attributes(self): self.assertEqual(experiment, impression_event.experiment) self.assertEqual(variation, impression_event.variation) self.assertEqual(user_id, impression_event.user_id) + self.assertEqual(self.project_config.region, impression_event.event_context.region) self.assertEqual( [x.__dict__ for x in expected_attrs], [x.__dict__ for x in impression_event.visitor_attributes], ) @@ -91,6 +106,7 @@ def test_conversion_event(self): self.assertEqual(self.project_config.bot_filtering, conversion_event.bot_filtering) self.assertEqual(self.project_config.get_event(event_key), conversion_event.event) self.assertEqual(user_id, conversion_event.user_id) + self.assertEqual(self.project_config.region, conversion_event.event_context.region) self.assertEqual( [x.__dict__ for x in expected_attrs], [x.__dict__ for x in conversion_event.visitor_attributes], ) @@ -117,6 +133,7 @@ def test_conversion_event__with_event_tags(self): self.assertEqual(self.project_config.bot_filtering, conversion_event.bot_filtering) self.assertEqual(self.project_config.get_event(event_key), conversion_event.event) self.assertEqual(user_id, conversion_event.user_id) + self.assertEqual(self.project_config.region, conversion_event.event_context.region) self.assertEqual( [x.__dict__ for x in expected_attrs], [x.__dict__ for x in conversion_event.visitor_attributes], ) From 08669627c058d2e59f29582863b9958e74af851f Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 15:30:28 +0400 Subject: [PATCH 02/25] Fix lint issues --- optimizely/event/user_event_factory.py | 12 ++++++++++-- tests/test_config.py | 3 --- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/optimizely/event/user_event_factory.py b/optimizely/event/user_event_factory.py index cd2791558..a15d8f578 100644 --- a/optimizely/event/user_event_factory.py +++ b/optimizely/event/user_event_factory.py @@ -76,7 +76,11 @@ def create_impression_event( variation = project_config.get_variation_from_id_by_experiment_id(experiment_id, variation_id) event_context = user_event.EventContext( - project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, project_config.region + project_config.account_id, + project_config.project_id, + project_config.revision, + project_config.anonymize_ip, + project_config.region ) return user_event.ImpressionEvent( @@ -115,7 +119,11 @@ def create_conversion_event( """ event_context = user_event.EventContext( - project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, project_config.region + project_config.account_id, + project_config.project_id, + project_config.revision, + project_config.anonymize_ip, + project_config.region ) return user_event.ConversionEvent( diff --git a/tests/test_config.py b/tests/test_config.py index 265b69044..2d7fff5fd 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -161,7 +161,6 @@ def test_region_when_no_region(self): project_config = opt_obj.config_manager.get_config() self.assertEqual(project_config.region, Region.US) - def test_region_when_specified_in_datafile(self): """ Test that region is set to 'US' when specified in the config. """ config_dict_us = copy.deepcopy(self.config_dict_with_multiple_experiments) @@ -177,8 +176,6 @@ def test_region_when_specified_in_datafile(self): project_config_eu = opt_obj_eu.config_manager.get_config() self.assertEqual(project_config_eu.region, Region.EU) - - def test_cmab_field_population(self): """ Test that the cmab field is populated correctly in experiments.""" From 5a0e19dd0d7783be6dd04c014d02e0e6a5597553 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 15:30:52 +0400 Subject: [PATCH 03/25] Fix lint issue --- tests/test_user_event_factory.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_user_event_factory.py b/tests/test_user_event_factory.py index f5bb2f8ea..4b9947277 100644 --- a/tests/test_user_event_factory.py +++ b/tests/test_user_event_factory.py @@ -55,7 +55,6 @@ def test_impression_event_with_region_eu(self): self.assertEqual(self.project_config.region, impression_event.event_context.region) self.assertEqual('EU', impression_event.event_context.region) - def test_impression_event__with_attributes(self): project_config = self.project_config experiment = self.project_config.get_experiment_from_key('test_experiment') From 730fede7d93401c80203dc175b942a5542fb574a Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 15:43:34 +0400 Subject: [PATCH 04/25] Fix errors --- optimizely/event/event_factory.py | 2 +- optimizely/event_builder.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/optimizely/event/event_factory.py b/optimizely/event/event_factory.py index 3dbbb8163..e2fa35316 100644 --- a/optimizely/event/event_factory.py +++ b/optimizely/event/event_factory.py @@ -101,7 +101,7 @@ def create_log_event( event_params = event_batch.get_event_params() region = user_context.region or 'US' - endpoint = cls.EVENT_ENDPOINTS.get(region) + endpoint = cls.EVENT_ENDPOINTS.get(region, cls.EVENT_ENDPOINTS['US']) return log_event.LogEvent(endpoint, event_params, cls.HTTP_VERB, cls.HTTP_HEADERS) diff --git a/optimizely/event_builder.py b/optimizely/event_builder.py index a243b94d3..383e44530 100644 --- a/optimizely/event_builder.py +++ b/optimizely/event_builder.py @@ -270,7 +270,7 @@ def create_impression_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(impression_params) region = project_config.region or 'US' - events_url = self.EVENTS_URLS.get(region) + events_url = self.EVENTS_URLS.get(region, self.EVENTS_URLS['US']) return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) @@ -297,6 +297,6 @@ def create_conversion_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params) region = project_config.region or 'US' - events_url = self.EVENTS_URLS.get(region) + events_url = self.EVENTS_URLS.get(region, self.EVENTS_URLS['US']) return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) From 47ccb94c9540db3f305452bf03c91f12cb1d0bd1 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 15:53:32 +0400 Subject: [PATCH 05/25] Add region on base test --- tests/base.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/base.py b/tests/base.py index 875a26e69..63344d4aa 100644 --- a/tests/base.py +++ b/tests/base.py @@ -57,6 +57,7 @@ def fake_server_response(self, status_code: Optional[int] = None, def setUp(self, config_dict='config_dict'): self.config_dict = { + 'region': 'US', 'revision': '42', 'sdkKey': 'basic-test', 'version': '2', @@ -150,6 +151,7 @@ def setUp(self, config_dict='config_dict'): # datafile version 4 self.config_dict_with_features = { + 'region': 'US', 'revision': '1', 'sdkKey': 'features-test', 'accountId': '12001', @@ -553,6 +555,7 @@ def setUp(self, config_dict='config_dict'): } self.config_dict_with_multiple_experiments = { + 'region': 'US', 'revision': '42', 'sdkKey': 'multiple-experiments', 'version': '2', @@ -686,6 +689,7 @@ def setUp(self, config_dict='config_dict'): 'accountId': '10367498574', 'events': [{'experimentIds': ['10420810910'], 'id': '10404198134', 'key': 'winning'}], 'revision': '1337', + 'region': 'US', } self.config_dict_with_typed_audiences = { @@ -1078,6 +1082,7 @@ def setUp(self, config_dict='config_dict'): ], 'revision': '3', 'sdkKey': 'typed-audiences', + 'region': 'US', } self.config_dict_with_audience_segments = { @@ -1274,7 +1279,8 @@ def setUp(self, config_dict='config_dict'): } ], 'revision': '101', - 'sdkKey': 'segments-test' + 'sdkKey': 'segments-test', + 'region': 'US', } config = getattr(self, config_dict) From a7d74acccee7a5b6c2c6439feda6215e3273fe2b Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 16:34:39 +0400 Subject: [PATCH 06/25] Update Region as enum --- optimizely/project_config.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index d13b28dd0..e6f676c5f 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -22,9 +22,9 @@ from .helpers import types if version_info < (3, 8): - from typing_extensions import Final, Literal + from typing_extensions import Final else: - from typing import Final, Literal # type: ignore + from typing import Final # type: ignore if TYPE_CHECKING: # prevent circular dependenacy by skipping import at runtime @@ -41,8 +41,9 @@ EntityClass = TypeVar('EntityClass') -Region = Literal['US', 'EU'] - +class Region(str, enums): + US = 'US' + EU = 'EU' class ProjectConfig: """ Representation of the Optimizely project config. """ From 8a65e0fe793a80f44ac27588f900a6e54ea7369a Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 16:39:52 +0400 Subject: [PATCH 07/25] Delete blank lines --- optimizely/project_config.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index e6f676c5f..b17d34e43 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -40,11 +40,9 @@ RESERVED_ATTRIBUTE_PREFIX: Final = '$opt_' EntityClass = TypeVar('EntityClass') - class Region(str, enums): US = 'US' EU = 'EU' - class ProjectConfig: """ Representation of the Optimizely project config. """ From 24d2fcd6d0e6a104e95d9928b7e7cbc5dae04f05 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 16:41:39 +0400 Subject: [PATCH 08/25] Fix lint issue --- optimizely/project_config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index b17d34e43..e6f676c5f 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -40,9 +40,11 @@ RESERVED_ATTRIBUTE_PREFIX: Final = '$opt_' EntityClass = TypeVar('EntityClass') + class Region(str, enums): US = 'US' EU = 'EU' + class ProjectConfig: """ Representation of the Optimizely project config. """ From ba5beee4fb5f79770c9c232f3b772a58f038110d Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 17:21:59 +0400 Subject: [PATCH 09/25] Fix lint issue --- optimizely/project_config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index e6f676c5f..8400068b8 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -41,10 +41,12 @@ EntityClass = TypeVar('EntityClass') + class Region(str, enums): US = 'US' EU = 'EU' + class ProjectConfig: """ Representation of the Optimizely project config. """ From 17c9280e281546ce1a732dd216de79dcc3b0b6d1 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 17:26:16 +0400 Subject: [PATCH 10/25] Fix test errors --- optimizely/project_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index 8400068b8..d46a57164 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -42,7 +42,7 @@ EntityClass = TypeVar('EntityClass') -class Region(str, enums): +class Region: US = 'US' EU = 'EU' From 155ab2545bb23a9521ec75a2850a7d0d12027ebf Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 17:32:30 +0400 Subject: [PATCH 11/25] Add enum --- optimizely/project_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index d46a57164..9ff054179 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -14,6 +14,7 @@ import json from typing import TYPE_CHECKING, Optional, Type, TypeVar, cast, Any, Iterable, List from sys import version_info +from enum import Enum from . import entities from . import exceptions @@ -42,7 +43,7 @@ EntityClass = TypeVar('EntityClass') -class Region: +class Region(str, Enum): US = 'US' EU = 'EU' From ba049b6df1b4ec63e97fb9516acb884a581dce6c Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 17:36:02 +0400 Subject: [PATCH 12/25] Fix region value --- optimizely/project_config.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index 9ff054179..58f123de5 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -90,7 +90,12 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any): self.public_key_for_odp: Optional[str] = None self.host_for_odp: Optional[str] = None self.all_segments: list[str] = [] - self.region: Region = config.get('region') or 'US' + + region_value = config.get('region') + if region_value == Region.EU.value: + self.region: Region = Region.EU + else: + self.region: Region = Region.US # Utility maps for quick lookup self.group_id_map: dict[str, entities.Group] = self._generate_key_map(self.groups, 'id', entities.Group) From a777fa0e0e8206f98fb389a0d28b628292d4e250 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 17:38:05 +0400 Subject: [PATCH 13/25] Fix type issue --- optimizely/project_config.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index 58f123de5..bfbf7ca5d 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -92,10 +92,11 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any): self.all_segments: list[str] = [] region_value = config.get('region') + self.region: Region if region_value == Region.EU.value: - self.region: Region = Region.EU + self.region = Region.EU else: - self.region: Region = Region.US + self.region = Region.US # Utility maps for quick lookup self.group_id_map: dict[str, entities.Group] = self._generate_key_map(self.groups, 'id', entities.Group) From c1f16938914c669ece074276356d82ba0d2b07ef Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 17:45:31 +0400 Subject: [PATCH 14/25] Correct the event url --- tests/test_event_builder.py | 35 +++++++++++++++++++++-------------- tests/test_event_factory.py | 7 +++++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/tests/test_event_builder.py b/tests/test_event_builder.py index fb4d7a0d3..818b939b2 100644 --- a/tests/test_event_builder.py +++ b/tests/test_event_builder.py @@ -100,7 +100,7 @@ def test_create_impression_event(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -155,7 +155,7 @@ def test_create_impression_event__with_attributes(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -208,7 +208,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -280,7 +280,7 @@ def side_effect(*args, **kwargs): self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -345,7 +345,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -409,7 +409,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -479,7 +479,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -515,6 +515,7 @@ def test_create_conversion_event(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -525,7 +526,7 @@ def test_create_conversion_event(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -563,6 +564,7 @@ def test_create_conversion_event__with_attributes(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -573,7 +575,7 @@ def test_create_conversion_event__with_attributes(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -618,6 +620,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -631,7 +634,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -681,6 +684,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -694,7 +698,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -735,6 +739,7 @@ def test_create_conversion_event__with_event_tags(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -749,7 +754,7 @@ def test_create_conversion_event__with_event_tags(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -788,6 +793,7 @@ def test_create_conversion_event__with_invalid_event_tags(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -802,7 +808,7 @@ def test_create_conversion_event__with_invalid_event_tags(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -843,6 +849,7 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -857,7 +864,7 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, diff --git a/tests/test_event_factory.py b/tests/test_event_factory.py index adbebd35c..781bffe3e 100644 --- a/tests/test_event_factory.py +++ b/tests/test_event_factory.py @@ -582,6 +582,7 @@ def test_create_conversion_event(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -629,6 +630,7 @@ def test_create_conversion_event__with_attributes(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -683,6 +685,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -744,6 +747,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -796,6 +800,7 @@ def test_create_conversion_event__with_event_tags(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -848,6 +853,7 @@ def test_create_conversion_event__with_invalid_event_tags(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -902,6 +908,7 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( From 6de08895c6a1a3cca13f0d1539d1336966d80819 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 18:05:08 +0400 Subject: [PATCH 15/25] Add region in params --- optimizely/event_builder.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/optimizely/event_builder.py b/optimizely/event_builder.py index 383e44530..04b6ec97a 100644 --- a/optimizely/event_builder.py +++ b/optimizely/event_builder.py @@ -269,6 +269,8 @@ def create_impression_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(impression_params) + params['region'] = str(project_config.region) + region = project_config.region or 'US' events_url = self.EVENTS_URLS.get(region, self.EVENTS_URLS['US']) @@ -296,6 +298,8 @@ def create_conversion_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params) + params['region'] = str(project_config.region) + region = project_config.region or 'US' events_url = self.EVENTS_URLS.get(region, self.EVENTS_URLS['US']) From 83afabe45060364260784238e54af4dac1b32d49 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 18:45:38 +0400 Subject: [PATCH 16/25] Fix region param --- optimizely/event_builder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/optimizely/event_builder.py b/optimizely/event_builder.py index 04b6ec97a..b3ea39c28 100644 --- a/optimizely/event_builder.py +++ b/optimizely/event_builder.py @@ -269,10 +269,10 @@ def create_impression_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(impression_params) - params['region'] = str(project_config.region) + params['region'] = project_config.region.value region = project_config.region or 'US' - events_url = self.EVENTS_URLS.get(region, self.EVENTS_URLS['US']) + events_url = self.EVENTS_URLS.get(str(region), self.EVENTS_URLS['US']) return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) @@ -298,9 +298,9 @@ def create_conversion_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params) - params['region'] = str(project_config.region) + params['region'] = project_config.region.value region = project_config.region or 'US' - events_url = self.EVENTS_URLS.get(region, self.EVENTS_URLS['US']) + events_url = self.EVENTS_URLS.get(str(region), self.EVENTS_URLS['US']) return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) From 158aab3b1f1633ed80bdd6e6edf27ffa61e69d1a Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 18:49:16 +0400 Subject: [PATCH 17/25] Add region to create --- optimizely/event_builder.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/optimizely/event_builder.py b/optimizely/event_builder.py index b3ea39c28..eb80bdd05 100644 --- a/optimizely/event_builder.py +++ b/optimizely/event_builder.py @@ -249,7 +249,8 @@ def _get_required_params_for_conversion( def create_impression_event( self, project_config: ProjectConfig, experiment: Experiment, - variation_id: str, user_id: str, attributes: UserAttributes + variation_id: str, user_id: str, attributes: UserAttributes, + region: str = 'US' ) -> Event: """ Create impression Event to be sent to the logging endpoint. @@ -278,7 +279,8 @@ def create_impression_event( def create_conversion_event( self, project_config: ProjectConfig, event_key: str, - user_id: str, attributes: UserAttributes, event_tags: event_tag_utils.EventTags + user_id: str, attributes: UserAttributes, event_tags: event_tag_utils.EventTags, + region: str = 'US' ) -> Event: """ Create conversion Event to be sent to the logging endpoint. From 0a0cdefe688db3465f15afa2e72d1f962659fded Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 18:58:15 +0400 Subject: [PATCH 18/25] Fix test cases --- tests/test_event_builder.py | 7 +++++++ tests/test_user_event_factory.py | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_event_builder.py b/tests/test_event_builder.py index 818b939b2..31cf32cdf 100644 --- a/tests/test_event_builder.py +++ b/tests/test_event_builder.py @@ -86,6 +86,7 @@ def test_create_impression_event(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -141,6 +142,7 @@ def test_create_impression_event__with_attributes(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -194,6 +196,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -250,6 +253,7 @@ def test_create_impression_event_calls_is_attribute_valid(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } def side_effect(*args, **kwargs): @@ -328,6 +332,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -392,6 +397,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -462,6 +468,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( diff --git a/tests/test_user_event_factory.py b/tests/test_user_event_factory.py index 4b9947277..4e4d17d1f 100644 --- a/tests/test_user_event_factory.py +++ b/tests/test_user_event_factory.py @@ -48,8 +48,10 @@ def test_impression_event_with_region_eu(self): experiment = self.project_config.get_experiment_from_key('test_experiment') user_id = 'test_user' + project_config.region = 'EU' + impression_event = UserEventFactory.create_impression_event( - project_config, experiment, '111128', '', 'rule_key', 'rule_type', True, user_id, None, region='EU' + project_config, experiment, '111128', '', 'rule_key', 'rule_type', True, user_id, None ) self.assertEqual(self.project_config.region, impression_event.event_context.region) From f68d67800feffd61f1277003b1f5b43ec8cd05bf Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 19:05:50 +0400 Subject: [PATCH 19/25] Fix test cases --- tests/test_event_factory.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_event_factory.py b/tests/test_event_factory.py index 781bffe3e..ebcfb9709 100644 --- a/tests/test_event_factory.py +++ b/tests/test_event_factory.py @@ -118,7 +118,7 @@ def test_create_impression_event(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_attributes(self): @@ -182,7 +182,7 @@ def test_create_impression_event__with_attributes(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_impression_event_when_attribute_is_not_in_datafile(self): @@ -244,7 +244,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_impression_event_calls_is_attribute_valid(self): @@ -323,7 +323,7 @@ def side_effect(*args, **kwargs): self._validate_event_object( log_event, - EventFactory.EVENT_ENDPOINT, + EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, @@ -399,7 +399,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_enabled(self,): @@ -471,7 +471,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled(self,): @@ -549,7 +549,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event(self): @@ -595,7 +595,7 @@ def test_create_conversion_event(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_attributes(self): @@ -643,7 +643,7 @@ def test_create_conversion_event__with_attributes(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled(self,): @@ -700,7 +700,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled(self,): @@ -762,7 +762,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_event_tags(self): @@ -817,7 +817,7 @@ def test_create_conversion_event__with_event_tags(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_invalid_event_tags(self): @@ -870,7 +870,7 @@ def test_create_conversion_event__with_invalid_event_tags(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__when_event_is_used_in_multiple_experiments(self): @@ -925,5 +925,5 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, ) From 81cd042f36d2fa91da554c35358af12fa3166897 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 19:11:32 +0400 Subject: [PATCH 20/25] Fix lint --- tests/test_event_factory.py | 78 ++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/tests/test_event_factory.py b/tests/test_event_factory.py index ebcfb9709..da58c4cb1 100644 --- a/tests/test_event_factory.py +++ b/tests/test_event_factory.py @@ -118,7 +118,11 @@ def test_create_impression_event(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_attributes(self): @@ -182,7 +186,11 @@ def test_create_impression_event__with_attributes(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event_when_attribute_is_not_in_datafile(self): @@ -244,7 +252,11 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event_calls_is_attribute_valid(self): @@ -399,7 +411,11 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_enabled(self,): @@ -471,7 +487,11 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled(self,): @@ -549,7 +569,11 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event(self): @@ -595,7 +619,11 @@ def test_create_conversion_event(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_attributes(self): @@ -643,7 +671,11 @@ def test_create_conversion_event__with_attributes(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled(self,): @@ -700,7 +732,11 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled(self,): @@ -762,7 +798,11 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_event_tags(self): @@ -817,7 +857,11 @@ def test_create_conversion_event__with_event_tags(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_invalid_event_tags(self): @@ -870,7 +914,11 @@ def test_create_conversion_event__with_invalid_event_tags(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__when_event_is_used_in_multiple_experiments(self): @@ -925,5 +973,9 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINTS.get('US'), expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) From 9d2c892d8948be5d00d26bf6ef784638fa967d21 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 2 Jul 2025 19:46:17 +0400 Subject: [PATCH 21/25] Add region --- tests/test_event_factory.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_event_factory.py b/tests/test_event_factory.py index da58c4cb1..b4d02cac2 100644 --- a/tests/test_event_factory.py +++ b/tests/test_event_factory.py @@ -98,6 +98,7 @@ def test_create_impression_event(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -166,6 +167,7 @@ def test_create_impression_event__with_attributes(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -232,6 +234,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -299,6 +302,7 @@ def test_create_impression_event_calls_is_attribute_valid(self): 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } def side_effect(*args, **kwargs): @@ -389,6 +393,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -465,6 +470,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( @@ -547,6 +553,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled 'enrich_decisions': True, 'anonymize_ip': False, 'revision': '42', + 'region': 'US', } with mock.patch('time.time', return_value=42.123), mock.patch( From 3c1332f8862ff2aa3a858d86c1a4a1625c5598a1 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 4 Jul 2025 13:11:14 +0400 Subject: [PATCH 22/25] Fix test cases --- optimizely/event/event_factory.py | 1 + optimizely/event/payload.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/optimizely/event/event_factory.py b/optimizely/event/event_factory.py index e2fa35316..5e3683238 100644 --- a/optimizely/event/event_factory.py +++ b/optimizely/event/event_factory.py @@ -93,6 +93,7 @@ def create_log_event( user_context.client_name, user_context.client_version, user_context.anonymize_ip, + user_context.region, True, ) diff --git a/optimizely/event/payload.py b/optimizely/event/payload.py index ac6f35e42..369172308 100644 --- a/optimizely/event/payload.py +++ b/optimizely/event/payload.py @@ -34,6 +34,7 @@ def __init__( anonymize_ip: bool, enrich_decisions: bool = True, visitors: Optional[list[Visitor]] = None, + region: str = 'US' ): self.account_id = account_id self.project_id = project_id @@ -43,6 +44,7 @@ def __init__( self.anonymize_ip = anonymize_ip self.enrich_decisions = enrich_decisions self.visitors = visitors or [] + self.region = region def __eq__(self, other: object) -> bool: batch_obj = self.get_event_params() From 11523cf6f0c3f801412f38a810729c6e37da4a94 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 4 Jul 2025 13:15:54 +0400 Subject: [PATCH 23/25] Fix tests --- optimizely/event/event_factory.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/optimizely/event/event_factory.py b/optimizely/event/event_factory.py index 5e3683238..a906b78a6 100644 --- a/optimizely/event/event_factory.py +++ b/optimizely/event/event_factory.py @@ -86,6 +86,7 @@ def create_log_event( return None user_context = first_event.event_context + region_value = user_context.region.value if hasattr(user_context.region, 'value') else user_context.region event_batch = payload.EventBatch( user_context.account_id, user_context.project_id, @@ -93,7 +94,7 @@ def create_log_event( user_context.client_name, user_context.client_version, user_context.anonymize_ip, - user_context.region, + region_value, True, ) From 1af68db0b4e490c112589b8c515f9d30f4e450f1 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 4 Jul 2025 13:19:57 +0400 Subject: [PATCH 24/25] Cast to string --- optimizely/event/event_factory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/optimizely/event/event_factory.py b/optimizely/event/event_factory.py index a906b78a6..66f50442f 100644 --- a/optimizely/event/event_factory.py +++ b/optimizely/event/event_factory.py @@ -102,8 +102,8 @@ def create_log_event( event_params = event_batch.get_event_params() - region = user_context.region or 'US' - endpoint = cls.EVENT_ENDPOINTS.get(region, cls.EVENT_ENDPOINTS['US']) + region_str = user_context.region.value if hasattr(user_context.region, 'value') else str(user_context.region) + endpoint = cls.EVENT_ENDPOINTS.get(region_str, cls.EVENT_ENDPOINTS['US']) return log_event.LogEvent(endpoint, event_params, cls.HTTP_VERB, cls.HTTP_HEADERS) From 7a09f1d8910eebba1ce4510d6a476106927911de Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 4 Jul 2025 15:01:11 +0400 Subject: [PATCH 25/25] Fix tests --- tests/test_event_builder.py | 16 +++++++--- tests/test_event_factory.py | 62 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/tests/test_event_builder.py b/tests/test_event_builder.py index 31cf32cdf..593d084c8 100644 --- a/tests/test_event_builder.py +++ b/tests/test_event_builder.py @@ -208,6 +208,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): '111129', 'test_user', {'do_you_know_me': 'test_value'}, + 'US' ) self._validate_event_object( event_obj, @@ -280,6 +281,7 @@ def side_effect(*args, **kwargs): '111129', 'test_user', attributes, + 'US', ) self._validate_event_object( @@ -346,6 +348,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( '111129', 'test_user', {'$opt_user_agent': 'Edge'}, + 'US' ) self._validate_event_object( @@ -411,6 +414,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en '111129', 'test_user', None, + 'US' ) self._validate_event_object( @@ -482,6 +486,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled '111129', 'test_user', {'$opt_user_agent': 'Chrome'}, + 'US' ) self._validate_event_object( @@ -529,7 +534,7 @@ def test_create_conversion_event(self): 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', None, None + self.project_config, 'test_event', 'test_user', None, None, 'US' ) self._validate_event_object( event_obj, @@ -578,7 +583,7 @@ def test_create_conversion_event__with_attributes(self): 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', {'test_attribute': 'test_value'}, None, + self.project_config, 'test_event', 'test_user', {'test_attribute': 'test_value'}, None, 'US' ) self._validate_event_object( event_obj, @@ -636,7 +641,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( 'optimizely.project_config.ProjectConfig.get_bot_filtering_value', return_value=True, ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Edge'}, None, + self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Edge'}, None, 'US' ) self._validate_event_object( @@ -700,7 +705,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled 'optimizely.project_config.ProjectConfig.get_bot_filtering_value', return_value=False, ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Chrome'}, None, + self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Chrome'}, None, 'US' ) self._validate_event_object( @@ -758,6 +763,7 @@ def test_create_conversion_event__with_event_tags(self): 'test_user', {'test_attribute': 'test_value'}, {'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'}, + 'US' ) self._validate_event_object( event_obj, @@ -812,6 +818,7 @@ def test_create_conversion_event__with_invalid_event_tags(self): 'test_user', {'test_attribute': 'test_value'}, {'revenue': '4200', 'value': True, 'non-revenue': 'abc'}, + 'US' ) self._validate_event_object( event_obj, @@ -868,6 +875,7 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel 'test_user', {'test_attribute': 'test_value'}, {'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'}, + 'US' ) self._validate_event_object( event_obj, diff --git a/tests/test_event_factory.py b/tests/test_event_factory.py index b4d02cac2..fd73582a1 100644 --- a/tests/test_event_factory.py +++ b/tests/test_event_factory.py @@ -312,39 +312,39 @@ def side_effect(*args, **kwargs): return False - attributes = { - 'test_attribute': 'test_value', - 'boolean_key': True, - 'integer_key': 0, - 'double_key': 5.5, - } - - with mock.patch('time.time', return_value=42.123), mock.patch( - 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' - ), mock.patch( - 'optimizely.helpers.validator.is_attribute_valid', side_effect=side_effect, - ): - - event_obj = UserEventFactory.create_impression_event( - self.project_config, - self.project_config.get_experiment_from_key('test_experiment'), - '111129', - '', - 'experiment', - 'test_user', - attributes, - ) - - log_event = EventFactory.create_log_event(event_obj, self.logger) - - self._validate_event_object( - log_event, - EventFactory.EVENT_ENDPOINTS.get('US'), - expected_params, - EventFactory.HTTP_VERB, - EventFactory.HTTP_HEADERS, + attributes = { + 'test_attribute': 'test_value', + 'boolean_key': True, + 'integer_key': 0, + 'double_key': 5.5, + } + + with mock.patch('time.time', return_value=42.123), mock.patch( + 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' + ), mock.patch( + 'optimizely.helpers.validator.is_attribute_valid', side_effect=side_effect, + ): + + event_obj = UserEventFactory.create_impression_event( + self.project_config, + self.project_config.get_experiment_from_key('test_experiment'), + '111129', + '', + 'experiment', + 'test_user', + attributes, ) + log_event = EventFactory.create_log_event(event_obj, self.logger) + + self._validate_event_object( + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, + ) + def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled(self,): """ Test that create_impression_event creates Event object with right params when user agent attribute is provided and pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy