Create the identity with the associated traits (optionally store traits if flag set on org)
(self, **kwargs)
| 143 | sensitive_fields = ("traits",) |
| 144 | |
| 145 | def save(self, **kwargs): # type: ignore[no-untyped-def] |
| 146 | """ |
| 147 | Create the identity with the associated traits |
| 148 | (optionally store traits if flag set on org) |
| 149 | """ |
| 150 | identifier = self.validated_data.get("identifier") |
| 151 | environment = self.context["environment"] |
| 152 | transient = self.validated_data["transient"] |
| 153 | sdk_trait_data: list[SDKTraitData] = self.validated_data.get("traits", []) |
| 154 | |
| 155 | if not identifier: |
| 156 | # We have a fully transient identity that should never be persisted. |
| 157 | identity, traits = get_transient_identity_and_traits( |
| 158 | environment=environment, |
| 159 | sdk_trait_data=sdk_trait_data, |
| 160 | ) |
| 161 | |
| 162 | elif transient: |
| 163 | # Don't persist incoming data but load presently stored |
| 164 | # overrides and traits, if any. |
| 165 | identity, traits = get_identified_transient_identity_and_traits( |
| 166 | environment=environment, |
| 167 | identifier=identifier, |
| 168 | sdk_trait_data=sdk_trait_data, |
| 169 | ) |
| 170 | |
| 171 | else: |
| 172 | # Persist the identity in accordance with individual trait transiency |
| 173 | # and persistence settings outside of request context. |
| 174 | identity, traits = get_persisted_identity_and_traits( |
| 175 | environment=environment, |
| 176 | identifier=identifier, |
| 177 | sdk_trait_data=sdk_trait_data, |
| 178 | ) |
| 179 | |
| 180 | all_feature_states = identity.get_all_feature_states( |
| 181 | traits=traits, |
| 182 | additional_filters=self.context.get("feature_states_additional_filters"), |
| 183 | ) |
| 184 | identify_integrations(identity, all_feature_states, traits) # type: ignore[no-untyped-call] |
| 185 | |
| 186 | return { |
| 187 | "identity": identity, |
| 188 | "identifier": identity.identifier, |
| 189 | "traits": traits, |
| 190 | "flags": all_feature_states, |
| 191 | } |
| 192 | |
| 193 | def validate_traits(self, traits: typing.List[dict] = None): # type: ignore[no-untyped-def,type-arg,assignment] |
| 194 | request = self.context["request"] |