Skip to content

Commit 1cd2b64

Browse files
fix: reapply before_send on repeated setup calls
- Keep before_send in sync with the module-level configuration on every setup() call, not just during initial client creation. - This fixes the case where the default client is initialized before posthog.before_send is assigned, causing later events to skip the callback unexpectedly. - Add a regression test covering updates to before_send after client initialization.
1 parent 854b6f7 commit 1cd2b64

3 files changed

Lines changed: 37 additions & 8 deletions

File tree

posthog/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,7 @@ def setup() -> Client:
889889
# always set incase user changes it
890890
default_client.disabled = disabled
891891
default_client.debug = debug
892+
default_client._set_before_send(before_send)
892893

893894
return default_client
894895

posthog/client.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,7 @@ def __init__(
288288
else:
289289
self.log.setLevel(logging.WARNING)
290290

291-
if before_send is not None:
292-
if callable(before_send):
293-
self.before_send = before_send
294-
else:
295-
self.log.warning("before_send is not callable, it will be ignored")
296-
self.before_send = None
297-
else:
298-
self.before_send = None
291+
self._set_before_send(before_send)
299292

300293
if self.enable_exception_autocapture:
301294
self.exception_capture = ExceptionCapture(self)
@@ -332,6 +325,16 @@ def __init__(
332325
if send:
333326
consumer.start()
334327

328+
def _set_before_send(self, before_send):
329+
if before_send is not None:
330+
if callable(before_send):
331+
self.before_send = before_send
332+
else:
333+
self.log.warning("before_send is not callable, it will be ignored")
334+
self.before_send = None
335+
else:
336+
self.before_send = None
337+
335338
def new_context(self, fresh=False, capture_exceptions=True):
336339
"""
337340
Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).

posthog/test/test_before_send.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,28 @@ def my_before_send(event):
248248
batch_data = mock_post.call_args[1]["batch"]
249249
enqueued_msg = batch_data[0]
250250
self.assertTrue(enqueued_msg["properties"]["module_level_before_send"])
251+
252+
def test_before_send_callback_updates_after_client_initialization(self):
253+
def my_before_send(event):
254+
event["properties"]["updated_after_init"] = True
255+
return event
256+
257+
with mock.patch("posthog.client.batch_post") as mock_post:
258+
posthog.api_key = FAKE_TEST_API_KEY
259+
posthog.sync_mode = True
260+
261+
first_msg_uuid = posthog.capture("first_event", distinct_id="user1")
262+
263+
posthog.before_send = my_before_send
264+
second_msg_uuid = posthog.capture("second_event", distinct_id="user1")
265+
266+
self.assertIsNotNone(first_msg_uuid)
267+
self.assertIsNotNone(second_msg_uuid)
268+
self.assertIs(posthog.default_client.before_send, my_before_send)
269+
270+
self.assertEqual(mock_post.call_count, 2)
271+
first_batch = mock_post.call_args_list[0][1]["batch"]
272+
second_batch = mock_post.call_args_list[1][1]["batch"]
273+
274+
self.assertNotIn("updated_after_init", first_batch[0]["properties"])
275+
self.assertTrue(second_batch[0]["properties"]["updated_after_init"])

0 commit comments

Comments
 (0)