Ejemplo n.º 1
0
    def test_store_classifier_data(self):
        """Test the store_classifier_data method."""
        exp_id = u'1'
        next_scheduled_check_time = datetime.datetime.utcnow()
        state_name = 'Home'
        interaction_id = 'TextInput'

        job_id = self._create_classifier_training_job(
            feconf.INTERACTION_CLASSIFIER_MAPPING['TextInput']['algorithm_id'],
            interaction_id, exp_id, 1, next_scheduled_check_time, [],
            state_name, feconf.TRAINING_JOB_STATUS_PENDING, {}, 1)

        # Retrieve classifier data from GCS and ensure that content is same.
        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        classifier_data = (
            self._get_classifier_data_from_classifier_training_job(
                classifier_training_job))
        self.assertEqual(json.loads(classifier_data.model_json), {})

        classifier_data_proto = text_classifier_pb2.TextClassifierFrozenModel()
        classifier_data_proto.model_json = json.dumps(
            {'classifier_data': 'data'})
        classifier_services.store_classifier_data(job_id,
                                                  classifier_data_proto)

        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        classifier_data = (
            self._get_classifier_data_from_classifier_training_job(
                classifier_training_job))
        self.assertDictEqual(json.loads(classifier_data.model_json),
                             {'classifier_data': 'data'})
Ejemplo n.º 2
0
    def post(self):
        """Handles POST requests."""
        payload_proto = (
            training_job_response_payload_pb2.TrainingJobResponsePayload())
        payload_proto.ParseFromString(self.request.body)

        if not validate_job_result_message_proto(payload_proto.job_result):
            raise self.InvalidInputException

        job_id = payload_proto.job_result.job_id

        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        if classifier_training_job.status == (
                feconf.TRAINING_JOB_STATUS_FAILED):
            # Send email to admin and admin-specified email recipients.
            # Other email recipients are specified on admin config page.
            email_manager.send_job_failure_email(job_id)
            raise self.InternalErrorException(
                'The current status of the job cannot transition to COMPLETE.')

        classifier_data_proto = getattr(
            payload_proto.job_result,
            payload_proto.job_result.WhichOneof('classifier_frozen_model'))
        classifier_services.store_classifier_data(
            job_id, classifier_data_proto)

        # Update status of the training job to 'COMPLETE'.
        classifier_services.mark_training_job_complete(job_id)

        return self.render_json({})
Ejemplo n.º 3
0
    def post(self):
        """Handles POST requests."""
        signature = self.payload.get('signature')
        message = self.payload.get('message')
        vm_id = self.payload.get('vm_id')
        if vm_id == feconf.DEFAULT_VM_ID and not feconf.DEV_MODE:
            raise self.UnauthorizedUserException

        if not validate_job_result_message_dict(message):
            raise self.InvalidInputException
        if not verify_signature(message, vm_id, signature):
            raise self.UnauthorizedUserException

        job_id = message['job_id']
        classifier_data = message['classifier_data']
        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        if classifier_training_job.status == (
                feconf.TRAINING_JOB_STATUS_FAILED):
            raise self.InternalErrorException(
                'The current status of the job cannot transition to COMPLETE.')
        try:
            classifier_services.store_classifier_data(job_id, classifier_data)
        except Exception as e:
            raise self.InternalErrorException(e)

        # Update status of the training job to 'COMPLETE'.
        classifier_services.mark_training_job_complete(job_id)

        return self.render_json({})
Ejemplo n.º 4
0
    def post(self):
        """Handles POST requests."""
        signature = self.payload.get('signature')
        message = self.payload.get('message')
        vm_id = self.payload.get('vm_id')
        if vm_id == feconf.DEFAULT_VM_ID and not constants.DEV_MODE:
            raise self.UnauthorizedUserException

        if not validate_job_result_message_dict(message):
            raise self.InvalidInputException
        if not verify_signature(message, vm_id, signature):
            raise self.UnauthorizedUserException

        job_id = message['job_id']
        # The classifier data received in the payload has all floating point
        # values stored as strings. This is because floating point numbers
        # are represented differently on GAE(Oppia) and GCE(Oppia-ml).
        # Therefore, converting all floating point numbers to string keeps
        # signature consistent on both Oppia and Oppia-ml.
        # For more info visit: https://stackoverflow.com/q/40173295
        classifier_data = (
            classifier_services.
            convert_strings_to_float_numbers_in_classifier_data(  #pylint: disable=line-too-long
                message['classifier_data_with_floats_stringified']))
        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        if classifier_training_job.status == (
                feconf.TRAINING_JOB_STATUS_FAILED):
            # Send email to admin and admin-specified email recipients.
            # Other email recipients are specified on admin config page.
            email_manager.send_job_failure_email(job_id)
            raise self.InternalErrorException(
                'The current status of the job cannot transition to COMPLETE.')
        try:
            classifier_services.store_classifier_data(job_id, classifier_data)
        except Exception as e:
            raise self.InternalErrorException(e)

        # Update status of the training job to 'COMPLETE'.
        classifier_services.mark_training_job_complete(job_id)

        return self.render_json({})
Ejemplo n.º 5
0
    def test_creation_of_state_classifier_mapping(self):
        super(ExplorationStateClassifierMappingTests, self).setUp()
        exploration_id = '15'

        self.login(self.VIEWER_EMAIL)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        exp_services.delete_demo(exploration_id)
        # We enable ENABLE_ML_CLASSIFIERS so that the subsequent call to
        # save_exploration handles job creation for trainable states.
        # Since only one demo exploration has a trainable state, we modify our
        # values for MIN_ASSIGNED_LABELS and MIN_TOTAL_TRAINING_EXAMPLES to let
        # the classifier_demo_exploration.yaml be trainable. This is
        # completely for testing purposes.
        with self.swap(feconf, 'ENABLE_ML_CLASSIFIERS', True):
            with self.swap(feconf, 'MIN_TOTAL_TRAINING_EXAMPLES', 5):
                with self.swap(feconf, 'MIN_ASSIGNED_LABELS', 1):
                    exp_services.load_demo(exploration_id)

        # Retrieve job_id of created job (because of save_exp).
        all_jobs = classifier_models.ClassifierTrainingJobModel.get_all()
        self.assertEqual(all_jobs.count(), 1)
        for job in all_jobs:
            job_id = job.id

        classifier_services.store_classifier_data(job_id, {})

        expected_state_classifier_mapping = {
            'text': {
                'algorithm_id': 'LDAStringClassifier',
                'classifier_data': {},
                'data_schema_version': 1
            }
        }
        # Call the handler.
        exploration_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, exploration_id))
        retrieved_state_classifier_mapping = exploration_dict[
            'state_classifier_mapping']

        self.assertEqual(expected_state_classifier_mapping,
                         retrieved_state_classifier_mapping)
Ejemplo n.º 6
0
    def test_store_classifier_data(self):
        """Test the store_classifier_data method."""
        exp_id = u'1'
        next_scheduled_check_time = datetime.datetime.utcnow()
        state_name = 'Home'
        interaction_id = 'TextInput'

        job_id = classifier_models.ClassifierTrainingJobModel.create(
            feconf.INTERACTION_CLASSIFIER_MAPPING['TextInput']['algorithm_id'],
            interaction_id, exp_id, 1, next_scheduled_check_time, [],
            state_name, feconf.TRAINING_JOB_STATUS_PENDING, None, 1)

        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        self.assertEqual(classifier_training_job.classifier_data, None)

        classifier_services.store_classifier_data(job_id, {})

        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        self.assertEqual(classifier_training_job.classifier_data, {})
Ejemplo n.º 7
0
 def test_can_not_store_classifier_data_due_to_invalid_job_id(self):
     with self.assertRaisesRegexp(
             Exception,
             'The ClassifierTrainingJobModel corresponding to the '
             'job_id of the ClassifierTrainingJob does not exist.'):
         classifier_services.store_classifier_data('invalid_job_id', {})