@@ -818,28 +818,7 @@ def get_feature_flag(
818818 distinct_id , groups , person_properties , group_properties
819819 )
820820
821- if self .feature_flags is None and self .personal_api_key :
822- self .load_feature_flags ()
823- response = None
824-
825- if self .feature_flags :
826- assert self .feature_flags_by_key is not None , "feature_flags_by_key should be initialized when feature_flags is set"
827- # Local evaluation
828- flag = self .feature_flags_by_key .get (key )
829- if flag :
830- try :
831- response = self ._compute_flag_locally (
832- flag ,
833- distinct_id ,
834- groups = groups ,
835- person_properties = person_properties ,
836- group_properties = group_properties ,
837- )
838- self .log .debug (f"Successfully computed flag locally: { key } -> { response } " )
839- except InconclusiveMatchError as e :
840- self .log .debug (f"Failed to compute flag { key } locally: { e } " )
841- except Exception as e :
842- self .log .exception (f"[FEATURE FLAGS] Error while computing variant locally: { e } " )
821+ response = self ._locally_evaluate_flag (key , distinct_id , groups , person_properties , group_properties )
843822
844823 flag_was_locally_evaluated = response is not None
845824 if not flag_was_locally_evaluated and not only_evaluate_locally :
@@ -878,6 +857,31 @@ def get_feature_flag(
878857 self .distinct_ids_feature_flags_reported [distinct_id ].add (feature_flag_reported_key )
879858 return response
880859
860+ def _locally_evaluate_flag (self , key : str , distinct_id : str , groups : dict [str , str ], person_properties : dict [str , str ], group_properties : dict [str , str ]) -> FlagValue | None :
861+ if self .feature_flags is None and self .personal_api_key :
862+ self .load_feature_flags ()
863+ response = None
864+
865+ if self .feature_flags :
866+ assert self .feature_flags_by_key is not None , "feature_flags_by_key should be initialized when feature_flags is set"
867+ # Local evaluation
868+ flag = self .feature_flags_by_key .get (key )
869+ if flag :
870+ try :
871+ response = self ._compute_flag_locally (
872+ flag ,
873+ distinct_id ,
874+ groups = groups ,
875+ person_properties = person_properties ,
876+ group_properties = group_properties ,
877+ )
878+ self .log .debug (f"Successfully computed flag locally: { key } -> { response } " )
879+ except InconclusiveMatchError as e :
880+ self .log .debug (f"Failed to compute flag { key } locally: { e } " )
881+ except Exception as e :
882+ self .log .exception (f"[FEATURE FLAGS] Error while computing variant locally: { e } " )
883+ return response
884+
881885 def get_feature_flag_payload (
882886 self ,
883887 key ,
@@ -895,18 +899,10 @@ def get_feature_flag_payload(
895899 return None
896900
897901 if match_value is None :
898- match_value = self .get_feature_flag (
899- key ,
900- distinct_id ,
901- groups = groups ,
902- person_properties = person_properties ,
903- group_properties = group_properties ,
904- send_feature_flag_events = False ,
905- # Disable automatic sending of feature flag events because we're manually handling event dispatch.
906- # This prevents sending events with empty data when `get_feature_flag` cannot be evaluated locally.
907- only_evaluate_locally = True , # Enable local evaluation of feature flags to avoid making multiple requests to `/decide`.
908- disable_geoip = disable_geoip ,
902+ person_properties , group_properties = self ._add_local_person_and_group_properties (
903+ distinct_id , groups , person_properties , group_properties
909904 )
905+ match_value = self ._locally_evaluate_flag (key , distinct_id , groups , person_properties , group_properties )
910906
911907 response = None
912908 payload = None
0 commit comments