@@ -206,14 +206,21 @@ def __init__(
206206
207207 @property
208208 def feature_flags (self ):
209+ """
210+ Get the local evaluation feature flags.
211+ """
209212 return self ._feature_flags
210213
211214 @feature_flags .setter
212215 def feature_flags (self , flags ):
216+ """
217+ Set the local evaluation feature flags.
218+ """
213219 self ._feature_flags = flags or []
214220 self .feature_flags_by_key = {
215221 flag ["key" ]: flag for flag in self ._feature_flags if flag .get ("key" ) is not None
216222 }
223+ assert self .feature_flags_by_key is not None , "feature_flags_by_key should be initialized when feature_flags is set"
217224
218225 def identify (self , distinct_id = None , properties = None , context = None , timestamp = None , uuid = None , disable_geoip = None ):
219226 if context is not None :
@@ -240,18 +247,27 @@ def identify(self, distinct_id=None, properties=None, context=None, timestamp=No
240247 def get_feature_variants (
241248 self , distinct_id , groups = None , person_properties = None , group_properties = None , disable_geoip = None
242249 ) -> dict [str , str | bool ]:
250+ """
251+ Get feature flag variants for a distinct_id by calling decide.
252+ """
243253 resp_data = self .get_decide (distinct_id , groups , person_properties , group_properties , disable_geoip )
244254 return to_values (resp_data ) or {}
245255
246256 def get_feature_payloads (
247257 self , distinct_id , groups = None , person_properties = None , group_properties = None , disable_geoip = None
248258 ) -> dict [str , str ]:
259+ """
260+ Get feature flag payloads for a distinct_id by calling decide.
261+ """
249262 resp_data = self .get_decide (distinct_id , groups , person_properties , group_properties , disable_geoip )
250263 return to_payloads (resp_data ) or {}
251264
252265 def get_feature_flags_and_payloads (
253266 self , distinct_id , groups = None , person_properties = None , group_properties = None , disable_geoip = None
254267 ) -> FlagsAndPayloads :
268+ """
269+ Get feature flags and payloads for a distinct_id by calling decide.
270+ """
255271 resp = self .get_decide (distinct_id , groups , person_properties , group_properties , disable_geoip )
256272 return to_flags_and_payloads (resp )
257273
@@ -783,7 +799,14 @@ def get_feature_flag(
783799 only_evaluate_locally = False ,
784800 send_feature_flag_events = True ,
785801 disable_geoip = None ,
786- ):
802+ ) -> FlagValue | None :
803+ """
804+ Get a feature flag value for a key by evaluating locally or remotely
805+ depending on whether local evaluation is enabled and the flag can be
806+ locally evaluated.
807+
808+ This also captures the $feature_flag_called event unless send_feature_flag_events is False.
809+ """
787810 require ("key" , key , string_types )
788811 require ("distinct_id" , distinct_id , ID_TYPES )
789812 require ("groups" , groups , dict )
@@ -800,24 +823,23 @@ def get_feature_flag(
800823 response = None
801824
802825 if self .feature_flags :
803- for flag in self .feature_flags :
804- if flag ["key" ] == key :
805- try :
806- response = self ._compute_flag_locally (
807- flag ,
808- distinct_id ,
809- groups = groups ,
810- person_properties = person_properties ,
811- group_properties = group_properties ,
812- )
813- self .log .debug (f"Successfully computed flag locally: { key } -> { response } " )
814- except InconclusiveMatchError as e :
815- self .log .debug (f"Failed to compute flag { key } locally: { e } " )
816- continue
817- except Exception as e :
818- self .log .exception (f"[FEATURE FLAGS] Error while computing variant locally: { e } " )
819- continue
820- break
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 } " )
821843
822844 flag_was_locally_evaluated = response is not None
823845 if not flag_was_locally_evaluated and not only_evaluate_locally :
0 commit comments