From 383096af9e9c597a23c86af76c45121ce6fc3d40 Mon Sep 17 00:00:00 2001
From: ozayr-zaviar <uzairzaviar@gmail.com>
Date: Fri, 18 Feb 2022 19:49:52 +0500
Subject: [PATCH 1/7] set BatchEventProcessor as default processor

---
 optimizely/optimizely.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/optimizely/optimizely.py b/optimizely/optimizely.py
index 10464a72..c315a97b 100644
--- a/optimizely/optimizely.py
+++ b/optimizely/optimizely.py
@@ -27,7 +27,7 @@
 from .decision_service import Decision
 from .error_handler import NoOpErrorHandler as noop_error_handler
 from .event import event_factory, user_event_factory
-from .event.event_processor import ForwardingEventProcessor
+from .event.event_processor import BatchEventProcessor
 from .event_dispatcher import EventDispatcher as default_event_dispatcher
 from .helpers import enums, validator
 from .helpers.enums import DecisionSources
@@ -88,8 +88,9 @@ def __init__(
         self.error_handler = error_handler or noop_error_handler
         self.config_manager = config_manager
         self.notification_center = notification_center or NotificationCenter(self.logger)
-        self.event_processor = event_processor or ForwardingEventProcessor(
+        self.event_processor = event_processor or BatchEventProcessor(
             self.event_dispatcher, logger=self.logger, notification_center=self.notification_center,
+            batch_size=1
         )
 
         if default_decide_options is None:

From 041423ec6996bec2a93b641abd8da200f7f4bbb6 Mon Sep 17 00:00:00 2001
From: ozayr-zaviar <uzairzaviar@gmail.com>
Date: Fri, 18 Feb 2022 22:19:54 +0500
Subject: [PATCH 2/7] tests fixed

---
 tests/test_optimizely.py | 74 ++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/tests/test_optimizely.py b/tests/test_optimizely.py
index f1956cf1..cff8a656 100644
--- a/tests/test_optimizely.py
+++ b/tests/test_optimizely.py
@@ -308,7 +308,7 @@ def test_activate(self):
         ) 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.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             self.assertEqual('variation', self.optimizely.activate('test_experiment', 'test_user'))
 
@@ -447,7 +447,7 @@ def on_activate(event_key, user_id, attributes, event_tags, event):
         with mock.patch(
                 'optimizely.decision_service.DecisionService.get_variation',
                 return_value=variation,
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process, mock.patch(
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast:
             self.assertEqual('variation', self.optimizely.activate('test_experiment', 'test_user'))
@@ -488,7 +488,7 @@ def on_activate(event_key, user_id, attributes, event_tags, event):
         with mock.patch(
                 'optimizely.decision_service.DecisionService.get_variation',
                 return_value=variation,
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process, mock.patch(
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast:
             self.assertEqual(
@@ -560,7 +560,7 @@ def on_track(event_key, user_id, attributes, event_tags, event):
         with mock.patch(
                 'optimizely.decision_service.DecisionService.get_variation',
                 return_value=(self.project_config.get_variation_from_id('test_experiment', '111128'), []),
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process, mock.patch(
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_event_tracked:
             self.optimizely.track('test_event', 'test_user')
@@ -582,7 +582,7 @@ def on_track(event_key, user_id, attributes, event_tags, event):
         with mock.patch(
                 'optimizely.decision_service.DecisionService.get_variation',
                 return_value=(self.project_config.get_variation_from_id('test_experiment', '111128'), []),
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process, mock.patch(
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_event_tracked:
             self.optimizely.track('test_event', 'test_user', attributes={'test_attribute': 'test_value'})
@@ -609,7 +609,7 @@ def on_track(event_key, user_id, attributes, event_tags, event):
         with mock.patch(
                 'optimizely.decision_service.DecisionService.get_variation',
                 return_value=(self.project_config.get_variation_from_id('test_experiment', '111128'), []),
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process, mock.patch(
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_event_tracked:
             self.optimizely.track(
@@ -681,7 +681,7 @@ def on_activate(experiment, user_id, attributes, variation, event):
                 return_value=(decision_service.Decision(mock_experiment,
                                                         mock_variation, enums.DecisionSources.ROLLOUT), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             self.assertTrue(opt_obj.is_feature_enabled('test_feature_in_experiment', 'test_user'))
 
@@ -702,7 +702,7 @@ def test_activate__with_attributes__audience_match(self):
         ) as mock_get_variation, mock.patch('time.time', return_value=42), mock.patch(
             'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
         ), mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             self.assertEqual(
                 'variation', self.optimizely.activate('test_experiment', 'test_user', {'test_attribute': 'test_value'}),
@@ -773,7 +773,7 @@ def test_activate__with_attributes_of_different_types(self):
         ) as mock_bucket, mock.patch('time.time', return_value=42), mock.patch(
             'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
         ), mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             attributes = {
                 'test_attribute': 'test_value_1',
@@ -850,7 +850,7 @@ def test_activate__with_attributes__typed_audience_match(self):
     variation when attributes are provided and typed audience conditions are met. """
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be included via exact match string audience with id '3468206642'
             self.assertEqual(
                 'A', opt_obj.activate('typed_audience_experiment', 'test_user', {'house': 'Gryffindor'}),
@@ -866,7 +866,7 @@ def test_activate__with_attributes__typed_audience_match(self):
 
         mock_process.reset()
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be included via exact match number audience with id '3468206646'
             self.assertEqual(
                 'A', opt_obj.activate('typed_audience_experiment', 'test_user', {'lasers': 45.5}),
@@ -885,7 +885,7 @@ def test_activate__with_attributes__typed_audience_with_semver_match(self):
     variation when attributes are provided and typed audience conditions are met. """
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be included via exact match string audience with id '18278344267'
             self.assertEqual(
                 'A', opt_obj.activate('typed_audience_experiment', 'test_user', {'android-release': '1.0.1'}),
@@ -901,7 +901,7 @@ def test_activate__with_attributes__typed_audience_with_semver_match(self):
 
         mock_process.reset()
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.assertEqual(
                 'A', opt_obj.activate('typed_audience_experiment', 'test_user', {'android-release': "1.2.2"}),
             )
@@ -936,7 +936,7 @@ def test_activate__with_attributes__complex_audience_match(self):
 
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be included via substring match string audience with id '3988293898', and
             # exact match number audience with id '3468206646'
             user_attr = {'house': 'Welcome to Slytherin!', 'lasers': 45.5}
@@ -979,7 +979,7 @@ def test_activate__with_attributes__audience_match__forced_bucketing(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.assertTrue(self.optimizely.set_forced_variation('test_experiment', 'test_user', 'control'))
             self.assertEqual(
                 'control', self.optimizely.activate('test_experiment', 'test_user', {'test_attribute': 'test_value'}),
@@ -1045,7 +1045,7 @@ def test_activate__with_attributes__audience_match__bucketing_id_provided(self):
         ) as mock_get_variation, mock.patch('time.time', return_value=42), mock.patch(
             'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
         ), mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             self.assertEqual(
                 'variation',
@@ -1234,7 +1234,7 @@ def test_track__with_attributes(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track('test_event', 'test_user', attributes={'test_attribute': 'test_value'})
 
         expected_params = {
@@ -1284,7 +1284,7 @@ def test_track__with_attributes__typed_audience_match(self):
 
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be included via substring match string audience with id '3988293898'
             opt_obj.track('item_bought', 'test_user', {'house': 'Welcome to Slytherin!'})
 
@@ -1304,7 +1304,7 @@ def test_track__with_attributes__typed_audience_mismatch(self):
 
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             opt_obj.track('item_bought', 'test_user', {'house': 'Welcome to Hufflepuff!'})
 
         self.assertEqual(1, mock_process.call_count)
@@ -1315,7 +1315,7 @@ def test_track__with_attributes__complex_audience_match(self):
 
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be included via exact match string audience with id '3468206642', and
             # exact match boolean audience with id '3468206643'
             user_attr = {'house': 'Gryffindor', 'should_do_it': True}
@@ -1346,7 +1346,7 @@ def test_track__with_attributes__complex_audience_mismatch(self):
 
         opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_typed_audiences))
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             # Should be excluded - exact match boolean audience with id '3468206643' does not match,
             # so the overall conditions fail
             user_attr = {'house': 'Gryffindor', 'should_do_it': False}
@@ -1360,7 +1360,7 @@ def test_track__with_attributes__bucketing_id_provided(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track(
                 'test_event',
                 'test_user',
@@ -1418,7 +1418,7 @@ def test_track__with_attributes__no_audience_match(self):
         """ Test that track calls process even if audience conditions do not match. """
 
         with mock.patch('time.time', return_value=42), mock.patch(
-                'optimizely.event.event_processor.ForwardingEventProcessor.process'
+                'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             self.optimizely.track(
                 'test_event', 'test_user', attributes={'test_attribute': 'wrong_test_value'},
@@ -1442,7 +1442,7 @@ def test_track__with_event_tags(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track(
                 'test_event',
                 'test_user',
@@ -1499,7 +1499,7 @@ def test_track__with_event_tags_revenue(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track(
                 'test_event',
                 'test_user',
@@ -1554,7 +1554,7 @@ def test_track__with_event_tags_numeric_metric(self):
         """ Test that track calls process with right params when only numeric metric
         event tags are provided. """
 
-        with mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        with mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track(
                 'test_event',
                 'test_user',
@@ -1585,7 +1585,7 @@ def test_track__with_event_tags__forced_bucketing(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.assertTrue(self.optimizely.set_forced_variation('test_experiment', 'test_user', 'variation'))
             self.optimizely.track(
                 'test_event',
@@ -1643,7 +1643,7 @@ def test_track__with_invalid_event_tags(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track(
                 'test_event',
                 'test_user',
@@ -1699,7 +1699,7 @@ def test_track__experiment_not_running(self):
         with mock.patch(
                 'optimizely.helpers.experiment.is_experiment_running', return_value=False
         ) as mock_is_experiment_running, mock.patch('time.time', return_value=42), mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process:
             self.optimizely.track('test_event', 'test_user')
 
@@ -1723,7 +1723,7 @@ def test_track__whitelisted_user_overrides_audience_check(self):
 
         with mock.patch('time.time', return_value=42), mock.patch(
                 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
-        ), mock.patch('optimizely.event.event_processor.ForwardingEventProcessor.process') as mock_process:
+        ), mock.patch('optimizely.event.event_processor.BatchEventProcessor.process') as mock_process:
             self.optimizely.track('test_event', 'user_1')
 
         self.assertEqual(1, mock_process.call_count)
@@ -1985,7 +1985,7 @@ def test_is_feature_enabled__returns_true_for_feature_experiment_if_feature_enab
                 return_value=(decision_service.Decision(mock_experiment,
                                                         mock_variation, enums.DecisionSources.FEATURE_TEST), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(
@@ -2085,7 +2085,7 @@ def test_is_feature_enabled__returns_false_for_feature_experiment_if_feature_dis
                 return_value=(decision_service.Decision(mock_experiment,
                                                         mock_variation, enums.DecisionSources.FEATURE_TEST), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(
@@ -2185,7 +2185,7 @@ def test_is_feature_enabled__returns_true_for_feature_rollout_if_feature_enabled
                 return_value=(decision_service.Decision(mock_experiment,
                                                         mock_variation, enums.DecisionSources.ROLLOUT), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(
@@ -2235,7 +2235,7 @@ def test_is_feature_enabled__returns_true_for_feature_rollout_if_feature_enabled
                 return_value=(decision_service.Decision(mock_experiment,
                                                         mock_variation, enums.DecisionSources.ROLLOUT), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(
@@ -2337,7 +2337,7 @@ def test_is_feature_enabled__returns_false_for_feature_rollout_if_feature_disabl
                 return_value=(decision_service.Decision(mock_experiment,
                                                         mock_variation, enums.DecisionSources.ROLLOUT), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(
@@ -2379,7 +2379,7 @@ def test_is_feature_enabled__returns_false_when_user_is_not_bucketed_into_any_va
                 'optimizely.decision_service.DecisionService.get_variation_for_feature',
                 return_value=(decision_service.Decision(None, None, enums.DecisionSources.ROLLOUT), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(
@@ -2423,7 +2423,7 @@ def test_is_feature_enabled__returns_false_when_variation_is_nil(self, ):
                 'optimizely.decision_service.DecisionService.get_variation_for_feature',
                 return_value=(decision_service.Decision(None, None, enums.DecisionSources.ROLLOUT), []),
         ) as mock_decision, mock.patch(
-            'optimizely.event.event_processor.ForwardingEventProcessor.process'
+            'optimizely.event.event_processor.BatchEventProcessor.process'
         ) as mock_process, mock.patch(
             'optimizely.notification_center.NotificationCenter.send_notifications'
         ) as mock_broadcast_decision, mock.patch(

From c8ec8131ce26a1ff433e4c2804bf29c51f596175 Mon Sep 17 00:00:00 2001
From: ozayr-zaviar <uzairzaviar@gmail.com>
Date: Sat, 19 Feb 2022 00:06:37 +0500
Subject: [PATCH 3/7] test case fixed and argument send in constructor

---
 optimizely/optimizely.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/optimizely/optimizely.py b/optimizely/optimizely.py
index c315a97b..35dbb353 100644
--- a/optimizely/optimizely.py
+++ b/optimizely/optimizely.py
@@ -52,7 +52,10 @@ def __init__(
             notification_center=None,
             event_processor=None,
             datafile_access_token=None,
-            default_decide_options=None
+            default_decide_options=None,
+            batch_size=1,
+            flush_interval=30,
+            timeout_interval=5
     ):
         """ Optimizely init method for managing Custom projects.
 
@@ -90,7 +93,7 @@ def __init__(
         self.notification_center = notification_center or NotificationCenter(self.logger)
         self.event_processor = event_processor or BatchEventProcessor(
             self.event_dispatcher, logger=self.logger, notification_center=self.notification_center,
-            batch_size=1
+            batch_size=batch_size, flush_interval=flush_interval, timeout_interval=timeout_interval
         )
 
         if default_decide_options is None:

From bd075c0511216b4034b4e4c21217178e8b3a1130 Mon Sep 17 00:00:00 2001
From: Andy Leap <andrew.leap@optimizely.com>
Date: Wed, 15 Jun 2022 10:23:18 -0400
Subject: [PATCH 4/7] auto start default event processor

---
 optimizely/optimizely.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/optimizely/optimizely.py b/optimizely/optimizely.py
index 7aa27254..95bcc439 100644
--- a/optimizely/optimizely.py
+++ b/optimizely/optimizely.py
@@ -91,7 +91,8 @@ def __init__(
         self.notification_center = notification_center or NotificationCenter(self.logger)
         self.event_processor = event_processor or BatchEventProcessor(
             self.event_dispatcher, logger=self.logger, notification_center=self.notification_center,
-            batch_size=batch_size, flush_interval=flush_interval, timeout_interval=timeout_interval
+            batch_size=batch_size, flush_interval=flush_interval, timeout_interval=timeout_interval,
+            start_on_init=True
         )
 
         if default_decide_options is None:

From ef509e745f090955bde3f1b5d76decba33eacdd9 Mon Sep 17 00:00:00 2001
From: Andy Leap <andrew.leap@optimizely.com>
Date: Wed, 15 Jun 2022 12:27:23 -0400
Subject: [PATCH 5/7] combine event processor parameters

---
 optimizely/optimizely.py | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/optimizely/optimizely.py b/optimizely/optimizely.py
index 95bcc439..336cd151 100644
--- a/optimizely/optimizely.py
+++ b/optimizely/optimizely.py
@@ -51,9 +51,7 @@ def __init__(
             event_processor=None,
             datafile_access_token=None,
             default_decide_options=None,
-            batch_size=1,
-            flush_interval=30,
-            timeout_interval=5
+            event_processor_options=None
     ):
         """ Optimizely init method for managing Custom projects.
 
@@ -81,6 +79,7 @@ def __init__(
                            optimizely.event.event_processor.BatchEventProcessor.
           datafile_access_token: Optional string used to fetch authenticated datafile for a secure project environment.
           default_decide_options: Optional list of decide options used with the decide APIs.
+          event_processor_options: Optional dict of options to be passed to the default batch event processor.
         """
         self.logger_name = '.'.join([__name__, self.__class__.__name__])
         self.is_valid = True
@@ -89,10 +88,19 @@ def __init__(
         self.error_handler = error_handler or noop_error_handler
         self.config_manager = config_manager
         self.notification_center = notification_center or NotificationCenter(self.logger)
+        event_processor_defaults = {
+            'batch_size': 1,
+            'flush_interval': 30,
+            'timeout_interval': 5,
+            'start_on_init': True
+        }
+        if event_processor_options:
+            event_processor_defaults.update(event_processor_options)
         self.event_processor = event_processor or BatchEventProcessor(
-            self.event_dispatcher, logger=self.logger, notification_center=self.notification_center,
-            batch_size=batch_size, flush_interval=flush_interval, timeout_interval=timeout_interval,
-            start_on_init=True
+            self.event_dispatcher,
+            logger=self.logger,
+            notification_center=self.notification_center,
+            **event_processor_defaults
         )
 
         if default_decide_options is None:

From ae8de644dbdbdeabee819f856fbb8a26db7e541f Mon Sep 17 00:00:00 2001
From: Andy Leap <andrew.leap@optimizely.com>
Date: Wed, 15 Jun 2022 17:03:05 -0400
Subject: [PATCH 6/7] increase event processor test timeout

---
 tests/test_event_processor.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_event_processor.py b/tests/test_event_processor.py
index 0656453c..4e45e6fc 100644
--- a/tests/test_event_processor.py
+++ b/tests/test_event_processor.py
@@ -116,7 +116,7 @@ class BatchEventProcessorTest(base.BaseTest):
     MAX_BATCH_SIZE = 10
     MAX_DURATION_SEC = 0.2
     MAX_TIMEOUT_INTERVAL_SEC = 0.1
-    TEST_TIMEOUT = 10
+    TEST_TIMEOUT = 15
 
     def setUp(self, *args, **kwargs):
         base.BaseTest.setUp(self, 'config_dict_with_multiple_experiments')

From 07b7dcf49b8238a8a4cb71f10b1808ac38df1ca8 Mon Sep 17 00:00:00 2001
From: Andy Leap <andrew.leap@optimizely.com>
Date: Wed, 15 Jun 2022 17:05:09 -0400
Subject: [PATCH 7/7] prevent event processor test interference

---
 tests/test_optimizely.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/test_optimizely.py b/tests/test_optimizely.py
index a235cf8d..380a5088 100644
--- a/tests/test_optimizely.py
+++ b/tests/test_optimizely.py
@@ -3335,7 +3335,11 @@ def test_get_all_feature_variables_for_feature_in_rollout(self):
     def test_get_feature_variable_for_feature_in_rollout(self):
         """ Test that get_feature_variable returns value as expected and broadcasts decision with proper parameters. """
 
-        opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
+        opt_obj = optimizely.Optimizely(
+            json.dumps(self.config_dict_with_features),
+            # prevent event processor from injecting notification calls
+            event_processor_options={'start_on_init': False}
+        )
         mock_experiment = opt_obj.config_manager.get_config().get_experiment_from_key('211127')
         mock_variation = opt_obj.config_manager.get_config().get_variation_from_id('211127', '211129')
         user_attributes = {'test_attribute': 'test_value'}