def experiment(parser, token):
    """
    Split Testing experiment tag has the following syntax :
    
    {% experiment <experiment_name> <alternative>  %}
    experiment content goes here
    {% endexperiment %}
    
    If the alternative name is neither 'test' nor 'control' an exception is raised
    during rendering.
    """
    try:
        token_contents = token.split_contents()
        experiment_name, alternative, weight, user_variable = _parse_token_contents(token_contents)

        node_list = parser.parse(('endexperiment', ))
        parser.delete_first_token()
    except ValueError:
        raise template.TemplateSyntaxError("Syntax should be like :"
                "{% experiment experiment_name alternative [weight=val] [user=val] %}")

    experiment = experiment_manager.get(experiment_name, None)
    if experiment:
        experiment.ensure_alternative_exists(alternative, weight)

    return ExperimentNode(node_list, experiment_name, alternative, user_variable)
    def confirm_human(self):
        if self.session.get('experiments_verified_human', False):
            return

        self.session['experiments_verified_human'] = True

        # Replay enrollments
        for enrollment in self._get_all_enrollments():
            enrollment.experiment.increment_participant_count(
                enrollment.alternative, self._participant_identifier())

        # Replay goals
        if 'experiments_goals' in self.session:
            try:
                for experiment_name, alternative, goal_name, count in self.session[
                        'experiments_goals']:
                    experiment = experiment_manager.get(experiment_name, None)
                    if experiment:
                        experiment.increment_goal_count(
                            alternative, goal_name,
                            self._participant_identifier(), count)
            except ValueError:
                pass  # Values from older version
            finally:
                del self.session['experiments_goals']
    def enroll(self, experiment_name, alternatives):
        """Enroll this user in the experiment if they are not already part of it. Returns the selected alternative"""
        chosen_alternative = conf.CONTROL_GROUP

        experiment = experiment_manager.get(experiment_name, None)
        if experiment and experiment.is_displaying_alternatives():
            if isinstance(alternatives, collections.Mapping):
                if conf.CONTROL_GROUP not in alternatives:
                    experiment.ensure_alternative_exists(conf.CONTROL_GROUP, 1)
                for alternative, weight in alternatives.items():
                    experiment.ensure_alternative_exists(alternative, weight)
            else:
                alternatives_including_control = alternatives + [
                    conf.CONTROL_GROUP
                ]
                for alternative in alternatives_including_control:
                    experiment.ensure_alternative_exists(alternative)

            assigned_alternative = self._get_enrollment(experiment)
            if assigned_alternative:
                chosen_alternative = assigned_alternative
            elif experiment.is_accepting_new_users(self._gargoyle_key()):
                chosen_alternative = experiment.random_alternative()
                self._set_enrollment(experiment, chosen_alternative)

        return chosen_alternative
def experiment(parser, token):
    """
    Split Testing experiment tag has the following syntax :

    {% experiment <experiment_name> <alternative> [weight=val] [user=val] %}
    experiment content goes here
    {% endexperiment %}

    One alternative should be called "control"

    """
    logger.debug('Entering "experiment" templatetag processor.')
    try:
        token_contents = token.split_contents()
        experiment_name, alternative, weight, user_variable = _parse_token_contents(token_contents)

        node_list = parser.parse(('endexperiment', ))
        parser.delete_first_token()
    except ValueError:
        raise template.TemplateSyntaxError(
            "Syntax should be like :{% experiment experiment_name alternative [weight=val] [user=val] %}")

    experiment = experiment_manager.get(experiment_name, None)
    if experiment:
        experiment.ensure_alternative_exists(alternative, weight)

    return ExperimentNode(node_list, experiment_name, alternative, user_variable)
Exemple #5
0
    def enroll(self, experiment_name, alternatives, force_alternative=None):
        """
        Enroll this user in the experiment if they are not already part of it. Returns the selected alternative

        force_alternative: Optionally force a user in an alternative at enrollment time
        """
        chosen_alternative = conf.CONTROL_GROUP

        experiment = experiment_manager.get(experiment_name, None)
        if experiment and experiment.is_displaying_alternatives():
            if isinstance(alternatives, collections.Mapping):
                if conf.CONTROL_GROUP not in alternatives:
                    experiment.ensure_alternative_exists(conf.CONTROL_GROUP, 1)
                for alternative, weight in alternatives.items():
                    experiment.ensure_alternative_exists(alternative, weight)
            else:
                alternatives_including_control = alternatives + [conf.CONTROL_GROUP]
                for alternative in alternatives_including_control:
                    experiment.ensure_alternative_exists(alternative)

            assigned_alternative = self._get_enrollment(experiment)
            if assigned_alternative:
                chosen_alternative = assigned_alternative
            elif experiment.is_accepting_new_users():
                if force_alternative:
                    chosen_alternative = force_alternative
                else:
                    chosen_alternative = experiment.random_alternative()
                self._set_enrollment(experiment, chosen_alternative)

        return chosen_alternative
def experiment(parser, token):
    """
    Split Testing experiment tag has the following syntax :
    
    {% experiment <experiment_name> <alternative>  %}
    experiment content goes here
    {% endexperiment %}
    
    If the alternative name is neither 'test' nor 'control' an exception is raised
    during rendering.
    """
    try:
        token_contents = token.split_contents()
        experiment_name, alternative, weight, user_variable = _parse_token_contents(
            token_contents)

        node_list = parser.parse(('endexperiment', ))
        parser.delete_first_token()
    except ValueError:
        raise template.TemplateSyntaxError(
            "Syntax should be like :"
            "{% experiment experiment_name alternative [weight=val] [user=val] %}"
        )

    experiment = experiment_manager.get(experiment_name, None)
    if experiment:
        experiment.ensure_alternative_exists(alternative, weight)

    return ExperimentNode(node_list, experiment_name, alternative,
                          user_variable)
Exemple #7
0
    def confirm_human(self):
        self.session[conf.CONFIRM_HUMAN_SESSION_KEY] = True
        logger.info(
            json.dumps({
                'type': 'confirm_human',
                'participant': self._participant_identifier()
            }))

        # Replay enrollments
        for enrollment in self._get_all_enrollments():
            self.experiment_counter.increment_participant_count(
                enrollment.experiment, enrollment.alternative,
                self._participant_identifier())

        # Replay goals
        if 'experiments_goals' in self.session:
            try:
                for experiment_name, alternative, goal_name, count in self.session[
                        'experiments_goals']:
                    experiment = experiment_manager.get(experiment_name, None)
                    if experiment:
                        self.experiment_counter.increment_goal_count(
                            experiment, alternative, goal_name,
                            self._participant_identifier(), count)
            except ValueError:
                pass  # Values from older version
            finally:
                del self.session['experiments_goals']
 def _get_all_enrollments(self):
     enrollments = self.session.get('experiments_enrollments', None)
     if enrollments:
         for experiment_name, data in enrollments.items():
             alternative, _ = data
             experiment = experiment_manager.get(experiment_name, None)
             if experiment:
                 yield experiment, alternative
 def _get_all_enrollments(self):
     enrollments = self.session.get('experiments_enrollments', None)
     if enrollments:
         for experiment_name, data in enrollments.items():
             alternative, _, enrollment_date, last_seen = _session_enrollment_latest_version(data)
             experiment = experiment_manager.get(experiment_name, None)
             if experiment:
                 yield EnrollmentData(experiment, alternative, enrollment_date, last_seen)
Exemple #10
0
 def get_alternative(self, experiment_name):
     """Get the alternative this user is enrolled in. If not enrolled in the experiment returns 'control'"""
     experiment = experiment_manager.get(experiment_name, None)
     if experiment and experiment.is_displaying_alternatives():
         alternative = self._get_enrollment(experiment)
         if alternative is not None:
             return alternative
     return "control"
Exemple #11
0
 def _get_all_enrollments(self):
     enrollments = self.session.get("experiments_enrollments", None)
     if enrollments:
         for experiment_name, data in enrollments.items():
             alternative, _, enrollment_date, last_seen = _session_enrollment_latest_version(data)
             experiment = experiment_manager.get(experiment_name, None)
             if experiment:
                 yield EnrollmentData(experiment, alternative, enrollment_date, last_seen)
Exemple #12
0
 def get_alternative(self, experiment_name):
     """Get the alternative this user is enrolled in. If not enrolled in the experiment returns 'control'"""
     experiment = experiment_manager.get(experiment_name, None)
     if experiment and experiment.is_displaying_alternatives():
         alternative = self._get_enrollment(experiment)
         if alternative is not None:
             return alternative
     return 'control'
Exemple #13
0
 def _get_all_enrollments(self):
     enrollments = self.session.get('experiments_enrollments', None)
     if enrollments:
         for experiment_name, data in enrollments.items():
             alternative, _ = data
             experiment = experiment_manager.get(experiment_name, None)
             if experiment:
                 yield experiment, alternative
Exemple #14
0
    def set_alternative(self, experiment_name, alternative):
        """Explicitly set the alternative the user is enrolled in for the specified experiment.

        This allows you to change a user between alternatives. The user and goal counts for the new
        alternative will be increment, but those for the old one will not be decremented. The user will
        be enrolled in the experiment even if the experiment would not normally accept this user."""
        experiment = experiment_manager.get(experiment_name, None)
        if experiment:
            self._set_enrollment(experiment, alternative)
Exemple #15
0
    def set_alternative(self, experiment_name, alternative):
        """Explicitly set the alternative the user is enrolled in for the specified experiment.

        This allows you to change a user between alternatives. The user and goal counts for the new
        alternative will be increment, but those for the old one will not be decremented. The user will
        be enrolled in the experiment even if the experiment would not normally accept this user."""
        experiment = experiment_manager.get(experiment_name, None)
        if experiment:
            self._set_enrollment(experiment, alternative)
Exemple #16
0
 def record_goal(self, goal_name):
     if self._is_verified_human():
         enrollments = self.session.get('experiments_enrollments', None)
         if not enrollments:
             return
         for experiment_name, (alternative, goals) in enrollments.items():
             experiment = experiment_manager.get(experiment_name, None)
             if experiment and experiment.is_displaying_alternatives():
                 experiment.increment_goal_count(alternative, goal_name, self._participant_identifier())
         return
     else:
         goals = self.session.get('experiments_goals', [])
         goals.append(goal_name) # Note, duplicates are allowed
         self.session['experiments_goals'] = goals
Exemple #17
0
 def record_goal(self, goal_name):
     if self._is_verified_human():
         enrollments = self.session.get('experiments_enrollments', None)
         if not enrollments:
             return
         for experiment_name, (alternative, goals) in enrollments.items():
             experiment = experiment_manager.get(experiment_name, None)
             if experiment and experiment.is_displaying_alternatives():
                 experiment.increment_goal_count(alternative, goal_name, self._participant_identifier())
         return
     else:
         # TODO: store temp goals and convert later when is_human is triggered
         # if verify human is called quick enough this should rarely happen.
         pass
Exemple #18
0
 def record_goal(self, goal_name):
     if self._is_verified_human():
         enrollments = self.session.get('experiments_enrollments', None)
         if not enrollments:
             return
         for experiment_name, (alternative, goals) in enrollments.items():
             experiment = experiment_manager.get(experiment_name, None)
             if experiment and experiment.is_displaying_alternatives():
                 experiment.increment_goal_count(
                     alternative, goal_name, self._participant_identifier())
         return
     else:
         goals = self.session.get('experiments_goals', [])
         goals.append(goal_name)  # Note, duplicates are allowed
         self.session['experiments_goals'] = goals
Exemple #19
0
    def confirm_human(self):
        if self.session.get('experiments_verified_human', False):
            return

        self.session['experiments_verified_human'] = True

        enrollments = self.session.get('experiments_enrollments', None)
        if not enrollments:
            return

        for experiment_name, data in enrollments.items():
            alternative, goals = data
            experiment = experiment_manager.get(experiment_name, None)
            if experiment:
                experiment.increment_participant_count(alternative, self._participant_identifier())
    def is_enrolled(self, experiment_name, alternative, request):
        """Test if the user is enrolled in the supplied alternative for the given experiment.

        The supplied alternative will be added to the list of possible alternatives for the
        experiment if it is not already there. If the user is not yet enrolled in the supplied
        experiment they will be enrolled, and an alternative chosen at random."""
        chosen_alternative = CONTROL_GROUP

        experiment = experiment_manager.get(experiment_name, None)
        if experiment and experiment.is_displaying_alternatives():
            experiment.ensure_alternative_exists(alternative)

            assigned_alternative = self.get_enrollment(experiment)
            if assigned_alternative:
                chosen_alternative = assigned_alternative
            elif experiment.is_accepting_new_users(request):
                chosen_alternative = experiment.random_alternative()
                self.set_enrollment(experiment, chosen_alternative)

        return alternative == chosen_alternative
    def render(self, context):
        experiment = experiment_manager.get(self.experiment_name, None)
        if experiment:
            experiment.ensure_alternative_exists(self.alternative, self.weight)

        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
        else:
            request = context.get('request', None)
            user = participant(request)

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
    def render(self, context):
        experiment = experiment_manager.get(self.experiment_name, None)
        if experiment:
            experiment.ensure_alternative_exists(self.alternative, self.weight)

        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
        else:
            request = context.get('request', None)
            user = participant(request)

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
Exemple #23
0
    def is_enrolled(self, experiment_name, alternative, request):
        """Test if the user is enrolled in the supplied alternative for the given experiment.

        The supplied alternative will be added to the list of possible alternatives for the
        experiment if it is not already there. If the user is not yet enrolled in the supplied
        experiment they will be enrolled, and an alternative chosen at random."""
        chosen_alternative = CONTROL_GROUP

        experiment = experiment_manager.get(experiment_name, None)
        if experiment and experiment.is_displaying_alternatives():
            experiment.ensure_alternative_exists(alternative)

            assigned_alternative = self.get_enrollment(experiment)
            if assigned_alternative:
                chosen_alternative = assigned_alternative
            elif experiment.is_accepting_new_users(request):
                chosen_alternative = experiment.random_alternative()
                self.set_enrollment(experiment, chosen_alternative)

        return alternative == chosen_alternative
Exemple #24
0
    def confirm_human(self):
        if self.session.get('experiments_verified_human', False):
            return

        self.session['experiments_verified_human'] = True

        # Replay enrollments
        for enrollment in self._get_all_enrollments():
            enrollment.experiment.increment_participant_count(enrollment.alternative, self._participant_identifier())

        # Replay goals
        if 'experiments_goals' in self.session:
            try:
                for experiment_name, alternative, goal_name, count in self.session['experiments_goals']:
                    experiment = experiment_manager.get(experiment_name, None)
                    if experiment:
                        experiment.increment_goal_count(alternative, goal_name, self._participant_identifier(), count)
            except ValueError:
                pass # Values from older version
            finally:
                del self.session['experiments_goals']
Exemple #25
0
    def confirm_human(self):
        if self.session.get('experiments_verified_human', False):
            return

        self.session['experiments_verified_human'] = True

        enrollments = self.session.get('experiments_enrollments', None)
        if not enrollments:
            return

        # Replay enrollments
        for experiment_name, data in enrollments.items():
            alternative, goals = data
            experiment = experiment_manager.get(experiment_name, None)
            if experiment:
                experiment.increment_participant_count(alternative, self._participant_identifier())

        # Replay goals
        if 'experiments_goals' in self.session:
            for goal_name in self.session['experiments_goals']:
                self.record_goal(goal_name) # Now we have verified human, these will be set
            del self.session['experiments_goals']
Exemple #26
0
    def confirm_human(self):
        self.session[conf.CONFIRM_HUMAN_SESSION_KEY] = True
        logger.info(json.dumps({"type": "confirm_human", "participant": self._participant_identifier()}))

        # Replay enrollments
        for enrollment in self._get_all_enrollments():
            self.experiment_counter.increment_participant_count(
                enrollment.experiment, enrollment.alternative, self._participant_identifier()
            )

        # Replay goals
        if "experiments_goals" in self.session:
            try:
                for experiment_name, alternative, goal_name, count in self.session["experiments_goals"]:
                    experiment = experiment_manager.get(experiment_name, None)
                    if experiment:
                        self.experiment_counter.increment_goal_count(
                            experiment, alternative, goal_name, self._participant_identifier(), count
                        )
            except ValueError:
                pass  # Values from older version
            finally:
                del self.session["experiments_goals"]
Exemple #27
0
    def confirm_human(self):
        if self.session.get('experiments_verified_human', False):
            return

        self.session['experiments_verified_human'] = True

        enrollments = self.session.get('experiments_enrollments', None)
        if not enrollments:
            return

        # Replay enrollments
        for experiment_name, data in enrollments.items():
            alternative, goals = data
            experiment = experiment_manager.get(experiment_name, None)
            if experiment:
                experiment.increment_participant_count(
                    alternative, self._participant_identifier())

        # Replay goals
        if 'experiments_goals' in self.session:
            for goal_name in self.session['experiments_goals']:
                self.record_goal(
                    goal_name)  # Now we have verified human, these will be set
            del self.session['experiments_goals']