|
1 | 1 | import typing |
2 | 2 |
|
| 3 | +from flag_engine.context.mappers import map_environment_identity_to_context |
3 | 4 | from flag_engine.environments.models import EnvironmentModel |
4 | 5 | from flag_engine.features.models import FeatureModel, FeatureStateModel |
5 | 6 | from flag_engine.identities.models import IdentityModel |
6 | 7 | from flag_engine.identities.traits.models import TraitModel |
7 | | -from flag_engine.segments.evaluator import get_identity_segments |
| 8 | +from flag_engine.segments.evaluator import get_context_segments |
8 | 9 | from flag_engine.utils.exceptions import FeatureStateNotFound |
9 | 10 |
|
10 | 11 |
|
@@ -99,26 +100,43 @@ def _get_identity_feature_states_dict( |
99 | 100 | override_traits: typing.Optional[typing.List[TraitModel]], |
100 | 101 | ) -> typing.Dict[FeatureModel, FeatureStateModel]: |
101 | 102 | # Get feature states from the environment |
102 | | - feature_states = {fs.feature: fs for fs in environment.feature_states} |
| 103 | + feature_states_by_feature = {fs.feature: fs for fs in environment.feature_states} |
| 104 | + |
| 105 | + context = map_environment_identity_to_context( |
| 106 | + environment=environment, |
| 107 | + identity=identity, |
| 108 | + ) |
| 109 | + if override_traits: |
| 110 | + if typing.TYPE_CHECKING: |
| 111 | + assert context["identity"] |
| 112 | + context["identity"].setdefault("traits", {}).update( |
| 113 | + {trait.trait_key: trait.trait_value for trait in override_traits} |
| 114 | + ) |
103 | 115 |
|
104 | 116 | # Override with any feature states defined by matching segments |
105 | | - identity_segments = get_identity_segments(environment, identity, override_traits) |
106 | | - for matching_segment in identity_segments: |
107 | | - for feature_state in matching_segment.feature_states: |
108 | | - if feature_state.feature in feature_states: |
109 | | - if feature_states[feature_state.feature].is_higher_segment_priority( |
110 | | - feature_state |
111 | | - ): |
112 | | - continue |
113 | | - feature_states[feature_state.feature] = feature_state |
| 117 | + for context_segment in get_context_segments( |
| 118 | + context=context, |
| 119 | + segments=environment.project.segments, |
| 120 | + ): |
| 121 | + for segment_feature_state in context_segment.feature_states: |
| 122 | + if ( |
| 123 | + environment_feature_state := feature_states_by_feature.get( |
| 124 | + segment_feature := segment_feature_state.feature |
| 125 | + ) |
| 126 | + ) and environment_feature_state.is_higher_segment_priority( |
| 127 | + segment_feature_state |
| 128 | + ): |
| 129 | + continue |
| 130 | + feature_states_by_feature[segment_feature] = segment_feature_state |
114 | 131 |
|
115 | 132 | # Override with any feature states defined directly the identity |
116 | | - feature_states.update( |
| 133 | + feature_states_by_feature.update( |
117 | 134 | { |
118 | | - fs.feature: fs |
119 | | - for fs in identity.identity_features |
120 | | - if fs.feature in feature_states |
| 135 | + identity_feature: identity_feature_state |
| 136 | + for identity_feature_state in identity.identity_features |
| 137 | + if (identity_feature := identity_feature_state.feature) |
| 138 | + in feature_states_by_feature |
121 | 139 | } |
122 | 140 | ) |
123 | 141 |
|
124 | | - return feature_states |
| 142 | + return feature_states_by_feature |
0 commit comments