77import requests
88from flag_engine import engine
99from flag_engine .environments .models import EnvironmentModel
10- from flag_engine .identities .models import IdentityModel , TraitModel
10+ from flag_engine .identities .models import IdentityModel
11+ from flag_engine .identities .traits .models import TraitModel
12+ from flag_engine .identities .traits .types import TraitValue
1113from flag_engine .segments .evaluator import get_identity_segments
1214from requests .adapters import HTTPAdapter
1315from urllib3 import Retry
@@ -94,6 +96,7 @@ def __init__(
9496 self .enable_realtime_updates = enable_realtime_updates
9597 self ._analytics_processor = None
9698 self ._environment = None
99+ self ._identity_overrides_by_identifier : typing .Dict [str , IdentityModel ] = {}
97100
98101 # argument validation
99102 if offline_mode and not offline_handler :
@@ -248,12 +251,21 @@ def get_identity_segments(
248251 )
249252
250253 traits = traits or {}
251- identity_model = self ._build_identity_model (identifier , ** traits )
254+ identity_model = self ._get_identity_model (identifier , ** traits )
252255 segment_models = get_identity_segments (self ._environment , identity_model )
253256 return [Segment (id = sm .id , name = sm .name ) for sm in segment_models ]
254257
255258 def update_environment (self ):
256259 self ._environment = self ._get_environment_from_api ()
260+ self ._update_overrides ()
261+
262+ def _update_overrides (self ) -> None :
263+ if not self ._environment :
264+ return
265+ if overrides := self ._environment .identity_overrides :
266+ self ._identity_overrides_by_identifier = {
267+ identity .identifier : identity for identity in overrides
268+ }
257269
258270 def _get_environment_from_api (self ) -> EnvironmentModel :
259271 environment_data = self ._get_json_response (self .environment_url , method = "GET" )
@@ -269,7 +281,7 @@ def _get_environment_flags_from_document(self) -> Flags:
269281 def _get_identity_flags_from_document (
270282 self , identifier : str , traits : typing .Dict [str , typing .Any ]
271283 ) -> Flags :
272- identity_model = self ._build_identity_model (identifier , ** traits )
284+ identity_model = self ._get_identity_model (identifier , ** traits )
273285 feature_states = engine .get_identity_feature_states (
274286 self ._environment , identity_model
275287 )
@@ -334,7 +346,11 @@ def _get_json_response(self, url: str, method: str, body: dict = None):
334346 "Unable to get valid response from Flagsmith API."
335347 ) from e
336348
337- def _build_identity_model (self , identifier : str , ** traits ):
349+ def _get_identity_model (
350+ self ,
351+ identifier : str ,
352+ ** traits : TraitValue ,
353+ ) -> IdentityModel :
338354 if not self ._environment :
339355 raise FlagsmithClientError (
340356 "Unable to build identity model when no local environment present."
@@ -344,6 +360,11 @@ def _build_identity_model(self, identifier: str, **traits):
344360 TraitModel (trait_key = key , trait_value = value )
345361 for key , value in traits .items ()
346362 ]
363+
364+ if identity := self ._identity_overrides_by_identifier .get (identifier ):
365+ identity .update_traits (trait_models )
366+ return identity
367+
347368 return IdentityModel (
348369 identifier = identifier ,
349370 environment_api_key = self ._environment .api_key ,
0 commit comments