@@ -313,6 +313,7 @@ def get_feature_variants(
313313 person_properties = None ,
314314 group_properties = None ,
315315 disable_geoip = None ,
316+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
316317 ) -> dict [str , Union [bool , str ]]:
317318 """
318319 Get feature flag variants for a user by calling decide.
@@ -323,12 +324,19 @@ def get_feature_variants(
323324 person_properties: A dictionary of person properties.
324325 group_properties: A dictionary of group properties.
325326 disable_geoip: Whether to disable GeoIP for this request.
327+ flag_keys_to_evaluate: A list of specific flag keys to evaluate. If provided,
328+ only these flags will be evaluated, improving performance.
326329
327330 Category:
328331 Feature Flags
329332 """
330333 resp_data = self .get_flags_decision (
331- distinct_id , groups , person_properties , group_properties , disable_geoip
334+ distinct_id ,
335+ groups ,
336+ person_properties ,
337+ group_properties ,
338+ disable_geoip ,
339+ flag_keys_to_evaluate ,
332340 )
333341 return to_values (resp_data ) or {}
334342
@@ -339,6 +347,7 @@ def get_feature_payloads(
339347 person_properties = None ,
340348 group_properties = None ,
341349 disable_geoip = None ,
350+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
342351 ) -> dict [str , str ]:
343352 """
344353 Get feature flag payloads for a user by calling decide.
@@ -349,6 +358,8 @@ def get_feature_payloads(
349358 person_properties: A dictionary of person properties.
350359 group_properties: A dictionary of group properties.
351360 disable_geoip: Whether to disable GeoIP for this request.
361+ flag_keys_to_evaluate: A list of specific flag keys to evaluate. If provided,
362+ only these flags will be evaluated, improving performance.
352363
353364 Examples:
354365 ```python
@@ -359,7 +370,12 @@ def get_feature_payloads(
359370 Feature Flags
360371 """
361372 resp_data = self .get_flags_decision (
362- distinct_id , groups , person_properties , group_properties , disable_geoip
373+ distinct_id ,
374+ groups ,
375+ person_properties ,
376+ group_properties ,
377+ disable_geoip ,
378+ flag_keys_to_evaluate ,
363379 )
364380 return to_payloads (resp_data ) or {}
365381
@@ -370,6 +386,7 @@ def get_feature_flags_and_payloads(
370386 person_properties = None ,
371387 group_properties = None ,
372388 disable_geoip = None ,
389+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
373390 ) -> FlagsAndPayloads :
374391 """
375392 Get feature flags and payloads for a user by calling decide.
@@ -380,6 +397,8 @@ def get_feature_flags_and_payloads(
380397 person_properties: A dictionary of person properties.
381398 group_properties: A dictionary of group properties.
382399 disable_geoip: Whether to disable GeoIP for this request.
400+ flag_keys_to_evaluate: A list of specific flag keys to evaluate. If provided,
401+ only these flags will be evaluated, improving performance.
383402
384403 Examples:
385404 ```python
@@ -390,7 +409,12 @@ def get_feature_flags_and_payloads(
390409 Feature Flags
391410 """
392411 resp = self .get_flags_decision (
393- distinct_id , groups , person_properties , group_properties , disable_geoip
412+ distinct_id ,
413+ groups ,
414+ person_properties ,
415+ group_properties ,
416+ disable_geoip ,
417+ flag_keys_to_evaluate ,
394418 )
395419 return to_flags_and_payloads (resp )
396420
@@ -401,6 +425,7 @@ def get_flags_decision(
401425 person_properties = None ,
402426 group_properties = None ,
403427 disable_geoip = None ,
428+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
404429 ) -> FlagsResponse :
405430 """
406431 Get feature flags decision.
@@ -411,6 +436,8 @@ def get_flags_decision(
411436 person_properties: A dictionary of person properties.
412437 group_properties: A dictionary of group properties.
413438 disable_geoip: Whether to disable GeoIP for this request.
439+ flag_keys_to_evaluate: A list of specific flag keys to evaluate. If provided,
440+ only these flags will be evaluated, improving performance.
414441
415442 Examples:
416443 ```python
@@ -441,6 +468,9 @@ def get_flags_decision(
441468 "geoip_disable" : disable_geoip ,
442469 }
443470
471+ if flag_keys_to_evaluate :
472+ request_data ["flag_keys_to_evaluate" ] = flag_keys_to_evaluate
473+
444474 resp_data = flags (
445475 self .api_key ,
446476 self .host ,
@@ -545,6 +575,7 @@ def capture(
545575 group_properties = flag_options ["group_properties" ],
546576 disable_geoip = disable_geoip ,
547577 only_evaluate_locally = True ,
578+ flag_keys_to_evaluate = flag_options ["flag_keys_filter" ],
548579 )
549580 else :
550581 # Default behavior - use remote evaluation
@@ -554,6 +585,7 @@ def capture(
554585 person_properties = flag_options ["person_properties" ],
555586 group_properties = flag_options ["group_properties" ],
556587 disable_geoip = disable_geoip ,
588+ flag_keys_to_evaluate = flag_options ["flag_keys_filter" ],
557589 )
558590 except Exception as e :
559591 self .log .exception (
@@ -595,7 +627,7 @@ def _parse_send_feature_flags(self, send_feature_flags) -> dict:
595627
596628 Returns:
597629 dict: Normalized options with keys: should_send, only_evaluate_locally,
598- person_properties, group_properties
630+ person_properties, group_properties, flag_keys_filter
599631
600632 Raises:
601633 TypeError: If send_feature_flags is not bool or dict
@@ -608,13 +640,15 @@ def _parse_send_feature_flags(self, send_feature_flags) -> dict:
608640 ),
609641 "person_properties" : send_feature_flags .get ("person_properties" ),
610642 "group_properties" : send_feature_flags .get ("group_properties" ),
643+ "flag_keys_filter" : send_feature_flags .get ("flag_keys_filter" ),
611644 }
612645 elif isinstance (send_feature_flags , bool ):
613646 return {
614647 "should_send" : send_feature_flags ,
615648 "only_evaluate_locally" : None ,
616649 "person_properties" : None ,
617650 "group_properties" : None ,
651+ "flag_keys_filter" : None ,
618652 }
619653 else :
620654 raise TypeError (
@@ -1184,12 +1218,12 @@ def _compute_flag_locally(
11841218 self .log .warning (
11851219 f"[FEATURE FLAGS] Unknown group type index { aggregation_group_type_index } for feature flag { feature_flag ['key' ]} "
11861220 )
1187- # failover to `/decide/ `
1221+ # failover to `/flags `
11881222 raise InconclusiveMatchError ("Flag has unknown group type index" )
11891223
11901224 if group_name not in groups :
11911225 # Group flags are never enabled in `groups` aren't passed in
1192- # don't failover to `/decide/ `, since response will be the same
1226+ # don't failover to `/flags `, since response will be the same
11931227 if warn_on_unknown_groups :
11941228 self .log .warning (
11951229 f"[FEATURE FLAGS] Can't compute group feature flag: { feature_flag ['key' ]} without group names passed in"
@@ -1317,7 +1351,7 @@ def _get_feature_flag_result(
13171351 )
13181352 elif not only_evaluate_locally :
13191353 try :
1320- flag_details , request_id = self ._get_feature_flag_details_from_decide (
1354+ flag_details , request_id = self ._get_feature_flag_details_from_server (
13211355 key ,
13221356 distinct_id ,
13231357 groups ,
@@ -1557,7 +1591,7 @@ def get_feature_flag_payload(
15571591 )
15581592 return feature_flag_result .payload if feature_flag_result else None
15591593
1560- def _get_feature_flag_details_from_decide (
1594+ def _get_feature_flag_details_from_server (
15611595 self ,
15621596 key : str ,
15631597 distinct_id : ID_TYPES ,
@@ -1567,10 +1601,15 @@ def _get_feature_flag_details_from_decide(
15671601 disable_geoip : Optional [bool ],
15681602 ) -> tuple [Optional [FeatureFlag ], Optional [str ]]:
15691603 """
1570- Calls /decide and returns the flag details and request id
1604+ Calls /flags and returns the flag details and request id
15711605 """
15721606 resp_data = self .get_flags_decision (
1573- distinct_id , groups , person_properties , group_properties , disable_geoip
1607+ distinct_id ,
1608+ groups ,
1609+ person_properties ,
1610+ group_properties ,
1611+ disable_geoip ,
1612+ flag_keys_to_evaluate = [key ],
15741613 )
15751614 request_id = resp_data .get ("requestId" )
15761615 flags = resp_data .get ("flags" )
@@ -1686,6 +1725,7 @@ def get_all_flags(
16861725 group_properties = None ,
16871726 only_evaluate_locally = False ,
16881727 disable_geoip = None ,
1728+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
16891729 ) -> Optional [dict [str , Union [bool , str ]]]:
16901730 """
16911731 Get all feature flags for a user.
@@ -1697,6 +1737,8 @@ def get_all_flags(
16971737 group_properties: A dictionary of group properties.
16981738 only_evaluate_locally: Whether to only evaluate locally.
16991739 disable_geoip: Whether to disable GeoIP for this request.
1740+ flag_keys_to_evaluate: A list of specific flag keys to evaluate. If provided,
1741+ only these flags will be evaluated, improving performance.
17001742
17011743 Examples:
17021744 ```python
@@ -1713,6 +1755,7 @@ def get_all_flags(
17131755 group_properties = group_properties ,
17141756 only_evaluate_locally = only_evaluate_locally ,
17151757 disable_geoip = disable_geoip ,
1758+ flag_keys_to_evaluate = flag_keys_to_evaluate ,
17161759 )
17171760
17181761 return response ["featureFlags" ]
@@ -1726,6 +1769,7 @@ def get_all_flags_and_payloads(
17261769 group_properties = None ,
17271770 only_evaluate_locally = False ,
17281771 disable_geoip = None ,
1772+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
17291773 ) -> FlagsAndPayloads :
17301774 """
17311775 Get all feature flags and their payloads for a user.
@@ -1737,6 +1781,8 @@ def get_all_flags_and_payloads(
17371781 group_properties: A dictionary of group properties.
17381782 only_evaluate_locally: Whether to only evaluate locally.
17391783 disable_geoip: Whether to disable GeoIP for this request.
1784+ flag_keys_to_evaluate: A list of specific flag keys to evaluate. If provided,
1785+ only these flags will be evaluated, improving performance.
17401786
17411787 Examples:
17421788 ```python
@@ -1760,6 +1806,7 @@ def get_all_flags_and_payloads(
17601806 groups = groups ,
17611807 person_properties = person_properties ,
17621808 group_properties = group_properties ,
1809+ flag_keys_to_evaluate = flag_keys_to_evaluate ,
17631810 )
17641811
17651812 if fallback_to_decide and not only_evaluate_locally :
@@ -1770,6 +1817,7 @@ def get_all_flags_and_payloads(
17701817 person_properties = person_properties ,
17711818 group_properties = group_properties ,
17721819 disable_geoip = disable_geoip ,
1820+ flag_keys_to_evaluate = flag_keys_to_evaluate ,
17731821 )
17741822 return to_flags_and_payloads (decide_response )
17751823 except Exception as e :
@@ -1787,6 +1835,7 @@ def _get_all_flags_and_payloads_locally(
17871835 person_properties = None ,
17881836 group_properties = None ,
17891837 warn_on_unknown_groups = False ,
1838+ flag_keys_to_evaluate : Optional [list [str ]] = None ,
17901839 ) -> tuple [FlagsAndPayloads , bool ]:
17911840 person_properties = person_properties or {}
17921841 group_properties = group_properties or {}
@@ -1799,7 +1848,15 @@ def _get_all_flags_and_payloads_locally(
17991848 fallback_to_decide = False
18001849 # If loading in previous line failed
18011850 if self .feature_flags :
1802- for flag in self .feature_flags :
1851+ # Filter flags based on flag_keys_to_evaluate if provided
1852+ flags_to_process = self .feature_flags
1853+ if flag_keys_to_evaluate :
1854+ flag_keys_set = set (flag_keys_to_evaluate )
1855+ flags_to_process = [
1856+ flag for flag in self .feature_flags if flag ["key" ] in flag_keys_set
1857+ ]
1858+
1859+ for flag in flags_to_process :
18031860 try :
18041861 flags [flag ["key" ]] = self ._compute_flag_locally (
18051862 flag ,
@@ -1815,7 +1872,7 @@ def _get_all_flags_and_payloads_locally(
18151872 if matched_payload is not None :
18161873 payloads [flag ["key" ]] = matched_payload
18171874 except InconclusiveMatchError :
1818- # No need to log this, since it's just telling us to fall back to `/decide `
1875+ # No need to log this, since it's just telling us to fall back to `/flags `
18191876 fallback_to_decide = True
18201877 except Exception as e :
18211878 self .log .exception (
0 commit comments