Skip to content

Commit d88fd0a

Browse files
committed
more pr feedback
1 parent f022e2a commit d88fd0a

File tree

3 files changed

+118
-31
lines changed

3 files changed

+118
-31
lines changed

posthog/client.py

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -398,50 +398,28 @@ def capture(
398398
extra_properties: dict[str, Any] = {}
399399
feature_variants: Optional[dict[str, Union[bool, str]]] = {}
400400

401-
# Parse send_feature_flags parameter
402-
should_send_flags = False
403-
only_evaluate_locally = None
404-
flag_person_properties = None
405-
flag_group_properties = None
401+
# Parse and normalize send_feature_flags parameter
402+
flag_options = self._parse_send_feature_flags(send_feature_flags)
406403

407-
if isinstance(send_feature_flags, dict):
408-
# SendFeatureFlagsOptions object
409-
should_send_flags = True
410-
only_evaluate_locally = send_feature_flags.get("only_evaluate_locally")
411-
flag_person_properties = send_feature_flags.get("person_properties")
412-
flag_group_properties = send_feature_flags.get("group_properties")
413-
elif send_feature_flags:
414-
# Boolean True
415-
should_send_flags = True
416-
417-
if should_send_flags:
404+
if flag_options["should_send"]:
418405
try:
419-
if only_evaluate_locally is True:
406+
if flag_options["only_evaluate_locally"] is True:
420407
# Only use local evaluation
421408
feature_variants = self.get_all_flags(
422409
distinct_id,
423410
groups=(groups or {}),
424-
person_properties=flag_person_properties,
425-
group_properties=flag_group_properties,
411+
person_properties=flag_options["person_properties"],
412+
group_properties=flag_options["group_properties"],
426413
disable_geoip=disable_geoip,
427414
only_evaluate_locally=True,
428415
)
429-
elif only_evaluate_locally is False:
430-
# Force remote evaluation via /decide
431-
feature_variants = self.get_feature_variants(
432-
distinct_id,
433-
groups,
434-
person_properties=flag_person_properties,
435-
group_properties=flag_group_properties,
436-
disable_geoip=disable_geoip,
437-
)
438416
else:
439417
# Default behavior - use remote evaluation
440418
feature_variants = self.get_feature_variants(
441419
distinct_id,
442420
groups,
443-
person_properties=flag_person_properties,
444-
group_properties=flag_group_properties,
421+
person_properties=flag_options["person_properties"],
422+
group_properties=flag_options["group_properties"],
445423
disable_geoip=disable_geoip,
446424
)
447425
except Exception as e:
@@ -474,6 +452,42 @@ def capture(
474452

475453
return self._enqueue(msg, disable_geoip)
476454

455+
def _parse_send_feature_flags(self, send_feature_flags) -> dict:
456+
"""
457+
Parse and normalize send_feature_flags parameter into a standard format.
458+
459+
Args:
460+
send_feature_flags: Either bool or SendFeatureFlagsOptions dict
461+
462+
Returns:
463+
dict: Normalized options with keys: should_send, only_evaluate_locally,
464+
person_properties, group_properties
465+
466+
Raises:
467+
TypeError: If send_feature_flags is not bool or dict
468+
"""
469+
if isinstance(send_feature_flags, dict):
470+
return {
471+
"should_send": True,
472+
"only_evaluate_locally": send_feature_flags.get(
473+
"only_evaluate_locally"
474+
),
475+
"person_properties": send_feature_flags.get("person_properties"),
476+
"group_properties": send_feature_flags.get("group_properties"),
477+
}
478+
elif isinstance(send_feature_flags, bool):
479+
return {
480+
"should_send": send_feature_flags,
481+
"only_evaluate_locally": None,
482+
"person_properties": None,
483+
"group_properties": None,
484+
}
485+
else:
486+
raise TypeError(
487+
f"Invalid type for send_feature_flags: {type(send_feature_flags)}. "
488+
f"Expected bool or dict."
489+
)
490+
477491
def set(self, **kwargs: Unpack[OptionalSetArgs]) -> Optional[str]:
478492
distinct_id = kwargs.get("distinct_id", None)
479493
properties = kwargs.get("properties", None)

posthog/test/test_client.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,3 +2173,76 @@ def test_get_remote_config_payload_requires_personal_api_key(self):
21732173
result = client.get_remote_config_payload("test-flag")
21742174

21752175
self.assertIsNone(result)
2176+
2177+
def test_parse_send_feature_flags_method(self):
2178+
"""Test the _parse_send_feature_flags helper method"""
2179+
client = Client(FAKE_TEST_API_KEY, sync_mode=True)
2180+
2181+
# Test boolean True
2182+
result = client._parse_send_feature_flags(True)
2183+
expected = {
2184+
"should_send": True,
2185+
"only_evaluate_locally": None,
2186+
"person_properties": None,
2187+
"group_properties": None,
2188+
}
2189+
self.assertEqual(result, expected)
2190+
2191+
# Test boolean False
2192+
result = client._parse_send_feature_flags(False)
2193+
expected = {
2194+
"should_send": False,
2195+
"only_evaluate_locally": None,
2196+
"person_properties": None,
2197+
"group_properties": None,
2198+
}
2199+
self.assertEqual(result, expected)
2200+
2201+
# Test options dict with all fields
2202+
options = {
2203+
"only_evaluate_locally": True,
2204+
"person_properties": {"plan": "premium"},
2205+
"group_properties": {"company": {"type": "enterprise"}},
2206+
}
2207+
result = client._parse_send_feature_flags(options)
2208+
expected = {
2209+
"should_send": True,
2210+
"only_evaluate_locally": True,
2211+
"person_properties": {"plan": "premium"},
2212+
"group_properties": {"company": {"type": "enterprise"}},
2213+
}
2214+
self.assertEqual(result, expected)
2215+
2216+
# Test options dict with partial fields
2217+
options = {"person_properties": {"user_id": "123"}}
2218+
result = client._parse_send_feature_flags(options)
2219+
expected = {
2220+
"should_send": True,
2221+
"only_evaluate_locally": None,
2222+
"person_properties": {"user_id": "123"},
2223+
"group_properties": None,
2224+
}
2225+
self.assertEqual(result, expected)
2226+
2227+
# Test empty dict
2228+
result = client._parse_send_feature_flags({})
2229+
expected = {
2230+
"should_send": True,
2231+
"only_evaluate_locally": None,
2232+
"person_properties": None,
2233+
"group_properties": None,
2234+
}
2235+
self.assertEqual(result, expected)
2236+
2237+
# Test invalid types
2238+
with self.assertRaises(TypeError) as cm:
2239+
client._parse_send_feature_flags("invalid")
2240+
self.assertIn("Invalid type for send_feature_flags", str(cm.exception))
2241+
2242+
with self.assertRaises(TypeError) as cm:
2243+
client._parse_send_feature_flags(123)
2244+
self.assertIn("Invalid type for send_feature_flags", str(cm.exception))
2245+
2246+
with self.assertRaises(TypeError) as cm:
2247+
client._parse_send_feature_flags(None)
2248+
self.assertIn("Invalid type for send_feature_flags", str(cm.exception))

posthog/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class SendFeatureFlagsOptions(TypedDict, total=False):
1515
Args:
1616
only_evaluate_locally: Whether to only use local evaluation for feature flags.
1717
If True, only flags that can be evaluated locally will be included.
18-
If False, remote evaluation via /decide API will be used when needed.
18+
If False, remote evaluation via /flags API will be used when needed.
1919
person_properties: Properties to use for feature flag evaluation specific to this event.
2020
These properties will be merged with any existing person properties.
2121
group_properties: Group properties to use for feature flag evaluation specific to this event.

0 commit comments

Comments
 (0)