66import sys
77import warnings
88from datetime import datetime , timedelta
9- from typing import Any
9+ from typing import Any , Optional , Union
1010from uuid import UUID , uuid4
1111
1212import distro # For Linux OS detection
1818from posthog .exception_utils import exc_info_from_error , exceptions_from_error_tuple , handle_in_app
1919from posthog .feature_flags import InconclusiveMatchError , match_feature_flag_properties
2020from posthog .poller import Poller
21- from posthog .request import (
22- DEFAULT_HOST ,
23- APIError ,
24- batch_post ,
25- decide ,
26- determine_server_host ,
27- get ,
28- remote_config ,
29- DecideResponse ,
30- )
31- from posthog .utils import SizeLimitedDict , clean , guess_timezone , remove_trailing_slash
32- from posthog .version import VERSION
21+ from posthog .request import DEFAULT_HOST , APIError , batch_post , decide , determine_server_host , get , remote_config
3322from posthog .types import (
34- FlagsAndPayloads ,
23+ DecideResponse ,
3524 FeatureFlag ,
36- FlagValue ,
3725 FlagMetadata ,
38- to_values ,
39- to_payloads ,
40- to_flags_and_payloads ,
26+ FlagsAndPayloads ,
27+ FlagValue ,
4128 normalize_decide_response ,
29+ to_flags_and_payloads ,
30+ to_payloads ,
31+ to_values ,
4232)
33+ from posthog .utils import SizeLimitedDict , clean , guess_timezone , remove_trailing_slash
34+ from posthog .version import VERSION
4335
4436try :
4537 import queue
@@ -265,7 +257,7 @@ def identify(self, distinct_id=None, properties=None, context=None, timestamp=No
265257
266258 def get_feature_variants (
267259 self , distinct_id , groups = None , person_properties = None , group_properties = None , disable_geoip = None
268- ) -> dict [str , str | bool ]:
260+ ) -> dict [str , Union [ bool , str ] ]:
269261 """
270262 Get feature flag variants for a distinct_id by calling decide.
271263 """
@@ -352,7 +344,7 @@ def capture(
352344 msg ["properties" ]["$groups" ] = groups
353345
354346 extra_properties : dict [str , Any ] = {}
355- feature_variants : dict [str , bool | str ] | None = {}
347+ feature_variants : Optional [ dict [str , Union [ bool , str ]]] = {}
356348 if send_feature_flags :
357349 try :
358350 feature_variants = self .get_feature_variants (distinct_id , groups , disable_geoip = disable_geoip )
@@ -820,7 +812,7 @@ def get_feature_flag(
820812 only_evaluate_locally = False ,
821813 send_feature_flag_events = True ,
822814 disable_geoip = None ,
823- ) -> FlagValue | None :
815+ ) -> Optional [ FlagValue ] :
824816 """
825817 Get a feature flag value for a key by evaluating locally or remotely
826818 depending on whether local evaluation is enabled and the flag can be
@@ -859,7 +851,7 @@ def get_feature_flag(
859851 self ._capture_feature_flag_called (
860852 distinct_id ,
861853 key ,
862- response ,
854+ response or False ,
863855 None ,
864856 flag_was_locally_evaluated ,
865857 groups ,
@@ -877,7 +869,7 @@ def _locally_evaluate_flag(
877869 groups : dict [str , str ],
878870 person_properties : dict [str , str ],
879871 group_properties : dict [str , str ],
880- ) -> FlagValue | None :
872+ ) -> Optional [ FlagValue ] :
881873 if self .feature_flags is None and self .personal_api_key :
882874 self .load_feature_flags ()
883875 response = None
@@ -949,7 +941,7 @@ def get_feature_flag_payload(
949941 self ._capture_feature_flag_called (
950942 distinct_id ,
951943 key ,
952- response ,
944+ response or False ,
953945 payload ,
954946 flag_was_locally_evaluated ,
955947 groups ,
@@ -967,33 +959,33 @@ def _get_feature_flag_details_from_decide(
967959 groups : dict [str , str ],
968960 person_properties : dict [str , str ],
969961 group_properties : dict [str , str ],
970- disable_geoip : bool | None ,
971- ) -> tuple [FeatureFlag | None , str ]:
962+ disable_geoip : Optional [ bool ] ,
963+ ) -> tuple [Optional [ FeatureFlag ], Optional [ str ] ]:
972964 """
973965 Calls /decide and returns the flag details and request id
974966 """
975967 resp_data = self .get_decide (distinct_id , groups , person_properties , group_properties , disable_geoip )
976968 request_id = resp_data .get ("requestId" )
977969 flags = resp_data .get ("flags" )
978- flag_details = flags .get (key )
970+ flag_details = flags .get (key ) if flags else None
979971 return flag_details , request_id
980972
981973 def _capture_feature_flag_called (
982974 self ,
983975 distinct_id : str ,
984976 key : str ,
985977 response : FlagValue ,
986- payload : str | None ,
978+ payload : Optional [ str ] ,
987979 flag_was_locally_evaluated : bool ,
988980 groups : dict [str , str ],
989- disable_geoip : bool | None ,
990- request_id : str | None ,
991- flag_details : FeatureFlag | None ,
981+ disable_geoip : Optional [ bool ] ,
982+ request_id : Optional [ str ] ,
983+ flag_details : Optional [ FeatureFlag ] ,
992984 ):
993985 feature_flag_reported_key = f"{ key } _{ str (response )} "
994986
995987 if feature_flag_reported_key not in self .distinct_ids_feature_flags_reported [distinct_id ]:
996- properties = {
988+ properties : dict [ str , Any ] = {
997989 "$feature_flag" : key ,
998990 "$feature_flag_response" : response ,
999991 "locally_evaluated" : flag_was_locally_evaluated ,
@@ -1043,7 +1035,7 @@ def get_remote_config_payload(self, key: str):
10431035 except Exception as e :
10441036 self .log .exception (f"[FEATURE FLAGS] Unable to get decrypted feature flag payload: { e } " )
10451037
1046- def _compute_payload_locally (self , key : str , match_value : FlagValue ) -> str | None :
1038+ def _compute_payload_locally (self , key : str , match_value : FlagValue ) -> Optional [ str ] :
10471039 payload = None
10481040
10491041 if self .feature_flags_by_key is None :
@@ -1068,7 +1060,7 @@ def get_all_flags(
10681060 group_properties = {},
10691061 only_evaluate_locally = False ,
10701062 disable_geoip = None ,
1071- ) -> dict [str , bool | str ] | None :
1063+ ) -> Optional [ dict [str , Union [ bool , str ]]] :
10721064 response = self .get_all_flags_and_payloads (
10731065 distinct_id ,
10741066 groups = groups ,
0 commit comments