Ejemplo n.º 1
0
    def test_should_raise_when_missing_model_file(self):
        # Given
        self.tmp_file_path.mkdir()

        # When / Then
        with self.assertRaises(LoadingError):
            SnipsNLUEngine.from_path(self.tmp_file_path)
Ejemplo n.º 2
0
    def test_should_raise_with_incompatible_model(self):
        # Given
        self.tmp_file_path.mkdir()
        engine_model_path = self.tmp_file_path / "nlu_engine.json"
        self.writeJsonContent(engine_model_path, {"model_version": "0.1.0"})

        # When / Then
        with self.assertRaises(IncompatibleModelError):
            SnipsNLUEngine.from_path(self.tmp_file_path)
Ejemplo n.º 3
0
    def test_train(self):
        # Given / When
        train(self.beverage_dataset_path, str(self.tmp_file_path))

        # Then
        if not self.tmp_file_path.exists():
            self.fail("No trained engine generated")
        msg = "Failed to create an engine from engine dict."
        with self.fail_if_exception(msg):
            SnipsNLUEngine.from_path(self.tmp_file_path)
Ejemplo n.º 4
0
    def test_should_persist_resources_from_memory(self):
        # Given
        dataset_stream = io.StringIO("""
---
type: intent
name: MakeTea
utterances:
- make me a [beverage_temperature:Temperature](hot) cup of tea
- make me [number_of_cups:snips/number](five) tea cups

---
type: intent
name: MakeCoffee
utterances:
- make me [number_of_cups:snips/number](one) cup of coffee please
- brew [number_of_cups] cups of coffee""")
        dataset = Dataset.from_yaml_files("en", [dataset_stream]).json
        shared = self.get_shared_data(dataset)
        engine = SnipsNLUEngine(**shared).fit(dataset)
        dir_temp_engine = self.fixture_dir / "temp_engine"
        engine.persist(dir_temp_engine)

        # When
        loaded_engine = SnipsNLUEngine.from_path(dir_temp_engine)
        shutil.rmtree(str(dir_temp_engine))

        # Then
        loaded_engine.to_byte_array()
Ejemplo n.º 5
0
    def test_should_parse_after_deserialization_from_dir(self):
        # Given
        dataset = BEVERAGE_DATASET
        engine = SnipsNLUEngine().fit(dataset)
        input_ = "Give me 3 cups of hot tea please"

        # When
        engine.persist(self.tmp_file_path)
        deserialized_engine = SnipsNLUEngine.from_path(self.tmp_file_path)
        result = deserialized_engine.parse(input_)

        # Then
        expected_slots = [
            resolved_slot({
                START: 8,
                END: 9
            }, "3", {
                "kind": "Number",
                "value": 3.0
            }, "snips/number", "number_of_cups"),
            custom_slot(
                unresolved_slot({
                    START: 18,
                    END: 21
                }, "hot", "Temperature", "beverage_temperature"))
        ]
        self.assertEqual(result[RES_INPUT], input_)
        self.assertEqual(result[RES_INTENT][RES_INTENT_NAME], "MakeTea")
        self.assertListEqual(result[RES_SLOTS], expected_slots)
Ejemplo n.º 6
0
    def test_should_bypass_model_version_check_when_specified(self):
        # Given
        dataset_stream = io.StringIO("""
---
type: intent
name: Greeting
utterances:
- hello world""")
        dataset = Dataset.from_yaml_files("en", [dataset_stream]).json

        with patch("snips_nlu.nlu_engine.nlu_engine.__model_version__",
                   "0.1.0"):
            engine = SnipsNLUEngine().fit(dataset)
            engine.persist(self.tmp_file_path)

        # When / Then
        SnipsNLUEngine.from_path(self.tmp_file_path, bypass_version_check=True)
Ejemplo n.º 7
0
    def test_should_be_deserializable_from_dir_when_empty(self):
        # Given
        engine = SnipsNLUEngine()
        engine.persist(self.tmp_file_path)

        # When
        engine = SnipsNLUEngine.from_path(self.tmp_file_path)

        # Then
        self.assertFalse(engine.fitted)
Ejemplo n.º 8
0
    def test_should_parse_after_deserialization_from_dir(self):
        # Given
        dataset_stream = io.StringIO("""
---
type: intent
name: MakeTea
utterances:
- make me a [beverage_temperature:Temperature](hot) cup of tea
- make me [number_of_cups:snips/number](five) tea cups
- i want [number_of_cups] cups of [beverage_temperature](boiling hot) tea pls
- can you prepare [number_of_cups] cup of [beverage_temperature](cold) tea ?

---
type: intent
name: MakeCoffee
utterances:
- make me [number_of_cups:snips/number](one) cup of coffee please
- brew [number_of_cups] cups of coffee
- can you prepare [number_of_cups] cup of coffee""")
        dataset = Dataset.from_yaml_files("en", [dataset_stream]).json
        shared = self.get_shared_data(dataset)
        engine = SnipsNLUEngine(**shared).fit(dataset)
        text = "Give me 3 cups of hot tea please"

        # When
        engine.persist(self.tmp_file_path)
        deserialized_engine = SnipsNLUEngine.from_path(self.tmp_file_path)
        result = deserialized_engine.parse(text)

        # Then
        expected_slots = [
            resolved_slot({
                START: 8,
                END: 9
            }, "3", {
                "kind": "Number",
                "value": 3.0
            }, "snips/number", "number_of_cups"),
            custom_slot(
                unresolved_slot({
                    START: 18,
                    END: 21
                }, "hot", "Temperature", "beverage_temperature"))
        ]
        self.assertEqual(result[RES_INPUT], text)
        self.assertEqual(result[RES_INTENT][RES_INTENT_NAME], "MakeTea")
        self.assertListEqual(result[RES_SLOTS], expected_slots)
Ejemplo n.º 9
0
    def test_should_be_deserializable(
            self, mocked_builtin_entity_parser, mocked_custom_entity_parser):
        # Given
        mocked_builtin_entity_parser.from_path = MagicMock()
        mocked_custom_entity_parser.from_path = MagicMock()

        @IntentParser.register("test_intent_parser1", True)
        class TestIntentParser1(MockIntentParser):
            pass

        @IntentParser.register("test_intent_parser2", True)
        class TestIntentParser2(MockIntentParser):
            pass

        dataset_metadata = {
            "language_code": "en",
            "entities": {
                "Temperature": {
                    "automatically_extensible": True,
                    "utterances": {
                        "boiling": "hot",
                        "cold": "cold",
                        "hot": "hot",
                        "iced": "cold"
                    }
                }
            },
            "slot_name_mappings": {
                "MakeCoffee": {
                    "number_of_cups": "snips/number"
                },
                "MakeTea": {
                    "beverage_temperature": "Temperature",
                    "number_of_cups": "snips/number"
                }
            },
        }
        engine_dict = {
            "unit_name": "nlu_engine",
            "dataset_metadata": dataset_metadata,
            "config": {
                "unit_name": "nlu_engine",
                "intent_parsers_configs": [
                    {
                        "unit_name": "test_intent_parser1"
                    },
                    {
                        "unit_name": "test_intent_parser2"
                    }
                ]
            },
            "intent_parsers": [
                "test_intent_parser1",
                "test_intent_parser2",
            ],
            "builtin_entity_parser": "builtin_entity_parser",
            "custom_entity_parser": "custom_entity_parser",
            "model_version": snips_nlu.__model_version__,
            "training_package_version": snips_nlu.__version__
        }
        self.tmp_file_path.mkdir()
        parser1_path = self.tmp_file_path / "test_intent_parser1"
        parser1_path.mkdir()
        parser2_path = self.tmp_file_path / "test_intent_parser2"
        parser2_path.mkdir()
        (self.tmp_file_path / "resources").mkdir()
        self.writeJsonContent(self.tmp_file_path / "nlu_engine.json",
                              engine_dict)
        self.writeJsonContent(
            parser1_path / "metadata.json",
            {"unit_name": "test_intent_parser1", "fitted": True})
        self.writeJsonContent(
            parser2_path / "metadata.json",
            {"unit_name": "test_intent_parser2", "fitted": True})

        # When
        engine = SnipsNLUEngine.from_path(self.tmp_file_path)

        # Then
        expected_engine_config = {
            "unit_name": "nlu_engine",
            "intent_parsers_configs": [
                {
                    "unit_name": "test_intent_parser1"
                },
                {
                    "unit_name": "test_intent_parser2"
                }
            ]
        }
        self.assertDictEqual(dataset_metadata, engine.dataset_metadata)
        self.assertDictEqual(expected_engine_config, engine.config.to_dict())
        self.assertIsInstance(engine.intent_parsers[0], TestIntentParser1)
        self.assertIsInstance(engine.intent_parsers[1], TestIntentParser2)
        mocked_custom_entity_parser.from_path.assert_called_once_with(
            self.tmp_file_path / "custom_entity_parser")
        mocked_builtin_entity_parser.from_path.assert_called_once_with(
            self.tmp_file_path / "builtin_entity_parser")
Ejemplo n.º 10
0
    def test_should_be_deserializable_from_dir(self):
        # Given
        register_processing_unit(TestIntentParser1)
        register_processing_unit(TestIntentParser2)

        dataset_metadata = {
            "language_code": "en",
            "entities": {
                "Temperature": {
                    "automatically_extensible": True,
                    "utterances": {
                        "boiling": "hot",
                        "cold": "cold",
                        "hot": "hot",
                        "iced": "cold"
                    }
                }
            },
            "slot_name_mappings": {
                "MakeCoffee": {
                    "number_of_cups": "snips/number"
                },
                "MakeTea": {
                    "beverage_temperature": "Temperature",
                    "number_of_cups": "snips/number"
                }
            },
        }
        parser1_config = TestIntentParser1Config()
        parser2_config = TestIntentParser2Config()
        engine_config = NLUEngineConfig([parser1_config, parser2_config])
        engine_dict = {
            "unit_name": "nlu_engine",
            "dataset_metadata": dataset_metadata,
            "config": engine_config.to_dict(),
            "intent_parsers": [
                "test_intent_parser1",
                "test_intent_parser2",
            ],
            "model_version": snips_nlu.__model_version__,
            "training_package_version": snips_nlu.__version__
        }
        self.tmp_file_path.mkdir()
        parser1_path = self.tmp_file_path / "test_intent_parser1"
        parser1_path.mkdir()
        parser2_path = self.tmp_file_path / "test_intent_parser2"
        parser2_path.mkdir()
        (self.tmp_file_path / "resources").mkdir()
        self.writeJsonContent(self.tmp_file_path / "nlu_engine.json",
                              engine_dict)
        self.writeJsonContent(parser1_path / "metadata.json",
                              {"unit_name": "test_intent_parser1"})
        self.writeJsonContent(parser2_path / "metadata.json",
                              {"unit_name": "test_intent_parser2"})

        # When
        engine = SnipsNLUEngine.from_path(self.tmp_file_path)

        # Then
        parser1_config = TestIntentParser1Config()
        parser2_config = TestIntentParser2Config()
        expected_engine_config = NLUEngineConfig(
            [parser1_config, parser2_config]).to_dict()
        # pylint:disable=protected-access
        self.assertDictEqual(engine._dataset_metadata, dataset_metadata)
        # pylint:enable=protected-access
        self.assertDictEqual(engine.config.to_dict(), expected_engine_config)