def activate(self, experiment_key, user_id, attributes=None):
    """ Buckets visitor and sends impression event to Optimizely.

    Args:
      experiment_key: Experiment which needs to be activated.
      user_id: ID for user.
      attributes: Dict representing user attributes and values which need to be recorded.

    Returns:
      Variation key representing the variation the user will be bucketed in.
      None if user is not in experiment or if experiment is not Running.
    """

    if not self.is_valid:
      self.logger.error(enums.Errors.INVALID_DATAFILE.format('activate'))
      return None

    if not validator.is_non_empty_string(experiment_key):
      self.logger.error(enums.Errors.INVALID_INPUT_ERROR.format('experiment_key'))
      return None

    if not isinstance(user_id, string_types):
      self.logger.error(enums.Errors.INVALID_INPUT_ERROR.format('user_id'))
      return None

    variation_key = self.get_variation(experiment_key, user_id, attributes)

    if not variation_key:
      self.logger.info('Not activating user "%s".' % user_id)
      return None

    experiment = self.config.get_experiment_from_key(experiment_key)
    variation = self.config.get_variation_from_key(experiment_key, variation_key)

    # Create and dispatch impression event
    self.logger.info('Activating user "%s" in experiment "%s".' % (user_id, experiment.key))
    self._send_impression_event(experiment, variation, user_id, attributes)

    return variation.key
Buckets visitor and sends impression event to Optimizely.

    Args:
      experiment_key: Experiment which needs to be activated.
      user_id: ID for user.
      attributes: Dict representing user attributes and values which need to be recorded.

    Returns:
      Variation key representing the variation the user will be bucketed in.
      None if user is not in experiment or if experiment is not Running.