def generate_trait_value_data(value: typing.Any):  # type: ignore[no-untyped-def]
        """
        Takes the value and returns dictionary
        to use for passing into trait value serializer

        :param value: trait value of variable type or deserialized output from TraitValueField
        :return: dictionary to pass directly into trait serializer
        """
        accepted_types = (STRING, INTEGER, BOOLEAN, FLOAT)

        # this method is called from multiple places in the code, some of which use
        # the data that has been deserialized by TraitValueField, this conditional
        # logic allows us to handle both cases
        # TODO: tidy this up (probably when we move to storing traits in dynamo?)
        if isinstance(value, dict) and value.get("type"):
            tv_type = value["type"]
            value = value["value"]
        else:
            tv_type = type(value).__name__

        return {
            # Default to string if not an anticipate type value to keep backwards compatibility.
            "value_type": tv_type if tv_type in accepted_types else STRING,
            Trait.get_trait_value_key_name(tv_type): value,  # type: ignore[no-untyped-call]
        }

        Takes the value and returns dictionary
        to use for passing into trait value serializer

        :param value: trait value of variable type or deserialized output from TraitValueField
        :return: dictionary to pass directly into trait serializer
        
api/environments/identities/traits/models.py