Skip to content

Commit 9b4938e

Browse files
committed
fix: Respect send_feature_flags when local eval is enabled
1 parent b179280 commit 9b4938e

File tree

2 files changed

+86
-10
lines changed

2 files changed

+86
-10
lines changed

posthog/client.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -679,15 +679,6 @@ def capture(
679679
f"[FEATURE FLAGS] Unable to get feature variants: {e}"
680680
)
681681

682-
elif self.feature_flags and event != "$feature_flag_called":
683-
# Local evaluation is enabled, flags are loaded, so try and get all flags we can without going to the server
684-
feature_variants = self.get_all_flags(
685-
distinct_id,
686-
groups=(groups or {}),
687-
disable_geoip=disable_geoip,
688-
only_evaluate_locally=True,
689-
)
690-
691682
for feature, variant in (feature_variants or {}).items():
692683
extra_properties[f"$feature/{feature}"] = variant
693684

posthog/test/test_client.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ def test_basic_capture_with_locally_evaluated_feature_flags(self, patch_flags):
409409
)
410410
client.feature_flags = [multivariate_flag, basic_flag, false_flag]
411411

412-
msg_uuid = client.capture("python test event", distinct_id="distinct_id")
412+
msg_uuid = client.capture(
413+
"python test event", distinct_id="distinct_id", send_feature_flags=True
414+
)
413415
self.assertIsNotNone(msg_uuid)
414416
self.assertFalse(self.failed)
415417

@@ -565,6 +567,7 @@ def test_dont_override_capture_with_local_flags(self, patch_flags):
565567
"python test event",
566568
distinct_id="distinct_id",
567569
properties={"$feature/beta-feature-local": "my-custom-variant"},
570+
send_feature_flags=True,
568571
)
569572
self.assertIsNotNone(msg_uuid)
570573
self.assertFalse(self.failed)
@@ -746,6 +749,88 @@ def test_basic_capture_with_feature_flags_switched_off_doesnt_send_them(
746749

747750
self.assertEqual(patch_flags.call_count, 0)
748751

752+
@mock.patch("posthog.client.flags")
753+
def test_capture_with_send_feature_flags_false_and_local_evaluation_doesnt_send_flags(
754+
self, patch_flags
755+
):
756+
"""Test that send_feature_flags=False with local evaluation enabled does NOT send flags"""
757+
patch_flags.return_value = {"featureFlags": {"beta-feature": "remote-variant"}}
758+
759+
multivariate_flag = {
760+
"id": 1,
761+
"name": "Beta Feature",
762+
"key": "beta-feature-local",
763+
"active": True,
764+
"rollout_percentage": 100,
765+
"filters": {
766+
"groups": [
767+
{
768+
"rollout_percentage": 100,
769+
},
770+
],
771+
"multivariate": {
772+
"variants": [
773+
{
774+
"key": "first-variant",
775+
"name": "First Variant",
776+
"rollout_percentage": 50,
777+
},
778+
{
779+
"key": "second-variant",
780+
"name": "Second Variant",
781+
"rollout_percentage": 50,
782+
},
783+
]
784+
},
785+
},
786+
}
787+
simple_flag = {
788+
"id": 2,
789+
"name": "Simple Flag",
790+
"key": "simple-flag",
791+
"active": True,
792+
"filters": {
793+
"groups": [
794+
{
795+
"rollout_percentage": 100,
796+
}
797+
],
798+
},
799+
}
800+
801+
with mock.patch("posthog.client.batch_post") as mock_post:
802+
client = Client(
803+
FAKE_TEST_API_KEY,
804+
on_error=self.set_fail,
805+
personal_api_key=FAKE_TEST_API_KEY,
806+
sync_mode=True,
807+
)
808+
client.feature_flags = [multivariate_flag, simple_flag]
809+
810+
msg_uuid = client.capture(
811+
"python test event",
812+
distinct_id="distinct_id",
813+
send_feature_flags=False,
814+
)
815+
self.assertIsNotNone(msg_uuid)
816+
self.assertFalse(self.failed)
817+
818+
# Get the enqueued message from the mock
819+
mock_post.assert_called_once()
820+
batch_data = mock_post.call_args[1]["batch"]
821+
msg = batch_data[0]
822+
823+
self.assertEqual(msg["event"], "python test event")
824+
self.assertEqual(msg["distinct_id"], "distinct_id")
825+
826+
# CRITICAL: Verify local flags are NOT included in the event
827+
self.assertNotIn("$feature/beta-feature-local", msg["properties"])
828+
self.assertNotIn("$feature/simple-flag", msg["properties"])
829+
self.assertNotIn("$active_feature_flags", msg["properties"])
830+
831+
# CRITICAL: Verify the /flags API was NOT called
832+
self.assertEqual(patch_flags.call_count, 0)
833+
749834
@mock.patch("posthog.client.flags")
750835
def test_capture_with_send_feature_flags_true_and_local_evaluation_uses_local_flags(
751836
self, patch_flags

0 commit comments

Comments
 (0)