def test_dump_config( tmp_path: Path, input_file: Text, expected_file: Text, capsys: CaptureFixture, autoconfig_keys: Set[Text], ): config_file = str(tmp_path / "config.yml") shutil.copyfile(str(CONFIG_FOLDER / input_file), config_file) old_config = rasa.shared.utils.io.read_model_configuration(config_file) DefaultV1Recipe.auto_configure(config_file, old_config) new_config = rasa.shared.utils.io.read_model_configuration(config_file) expected = rasa.shared.utils.io.read_model_configuration(CONFIG_FOLDER / expected_file) assert new_config == expected captured = capsys.readouterr() assert "does not exist or is empty" not in captured.out for k in CONFIG_AUTOCONFIGURABLE_KEYS: if k in autoconfig_keys: assert k in captured.out else: assert k not in captured.out
def test_register_component_with_multiple_types(): @DefaultV1Recipe.register( [ DefaultV1Recipe.ComponentType.MESSAGE_TOKENIZER, DefaultV1Recipe.ComponentType.MODEL_LOADER, ], is_trainable=True, model_from="Herman", ) class MyClassGraphComponent(GraphComponent): @classmethod def create( cls, config: Dict[Text, Any], model_storage: ModelStorage, resource: Resource, execution_context: ExecutionContext, ) -> GraphComponent: return cls() assert DefaultV1Recipe._from_registry( MyClassGraphComponent.__name__) == DefaultV1Recipe.RegisteredComponent( MyClassGraphComponent, { DefaultV1Recipe.ComponentType.MESSAGE_TOKENIZER, DefaultV1Recipe.ComponentType.MODEL_LOADER, }, True, "Herman", ) assert MyClassGraphComponent()
def test_retrieve_not_registered_class(): class NotRegisteredClass: pass with pytest.raises(InvalidConfigException): # noinspection PyTypeChecker DefaultV1Recipe._from_registry(NotRegisteredClass.__name__)
def test_no_warnings_with_default_project(tmp_path: Path): rasa.utils.common.copy_directory(Path("rasa/cli/initial_project"), tmp_path) importer = TrainingDataImporter.load_from_config( config_path=str(tmp_path / "config.yml"), domain_path=str(tmp_path / "domain.yml"), training_data_paths=[str(tmp_path / "data")], ) config, _missing_keys, _configured_keys = DefaultV1Recipe.auto_configure( importer.get_config_file_for_auto_config(), importer.get_config(), TrainingType.END_TO_END, ) graph_config = DefaultV1Recipe().graph_config_for_recipe( config, cli_parameters={}, training_type=TrainingType.END_TO_END) validator = DefaultV1RecipeValidator(graph_config.train_schema) with pytest.warns( UserWarning, match="Slot auto-fill has been removed in 3.0") as records: validator.validate(importer) assert all([ warn.message.args[0].startswith("Slot auto-fill has been removed") for warn in records.list ])
def test_add_missing_config_keys_to_file(tmp_path: Path, config_path: Path, missing_keys: Set[Text]): config_file = str(tmp_path / "config.yml") shutil.copyfile(str(config_path), config_file) DefaultV1Recipe._add_missing_config_keys_to_file(config_file, missing_keys) config_after_addition = rasa.shared.utils.io.read_config_file(config_file) assert all(key in config_after_addition for key in missing_keys)
def test_importer_with_invalid_model_config(tmp_path: Path): invalid = {"version": "2.0", "policies": ["name"]} config_file = tmp_path / "config.yml" rasa.shared.utils.io.write_yaml(invalid, config_file) with pytest.raises(YamlValidationException): importer = TrainingDataImporter.load_from_config(str(config_file)) DefaultV1Recipe.auto_configure( importer.get_config_file_for_auto_config(), importer.get_config(), TrainingType.END_TO_END, )
def test_dump_config_missing_file(tmp_path: Path, capsys: CaptureFixture): config_path = tmp_path / "non_existent_config.yml" config = rasa.shared.utils.io.read_config_file(str(SOME_CONFIG)) DefaultV1Recipe._dump_config(config, str(config_path), set(), {"policies"}) assert not config_path.exists() captured = capsys.readouterr() assert "has been removed or modified" in captured.out
def test_retrieve_via_invalid_module_path(): with pytest.raises(ImportError): path = "rasa.core.policies.ted_policy.TEDPolicy1000" DefaultV1Recipe().graph_config_for_recipe( {"policies": [{ "name": path }]}, {}, TrainingType.CORE)
def recipe_for_name(name: Optional[Text]) -> Recipe: """Returns `Recipe` based on an optional recipe identifier. Args: name: The identifier which is used to select a certain `Recipe`. If `None` the default recipe will be used. Returns: A recipe which can be used to convert a given config to train and predict graph schemas. """ from rasa.engine.recipes.default_recipe import DefaultV1Recipe from rasa.engine.recipes.graph_recipe import GraphV1Recipe if name is None: rasa.shared.utils.io.raise_deprecation_warning( "From Rasa Open Source 4.0.0 onwards it will be required to specify " "a recipe in your model configuration. Defaulting to recipe " f"'{DefaultV1Recipe.name}'." ) return DefaultV1Recipe() recipes = { DefaultV1Recipe.name: DefaultV1Recipe, GraphV1Recipe.name: GraphV1Recipe, } recipe_constructor = recipes.get(name) if recipe_constructor: return recipe_constructor() raise InvalidRecipeException( f"No recipe with name '{name}' was found. " f"Available recipes are: " f"'{DefaultV1Recipe.name}'." )
def test_train_core_without_nlu_pipeline(): with pytest.raises(InvalidConfigException): DefaultV1Recipe().graph_config_for_recipe( {"policies": []}, {}, TrainingType.CORE, )
def test_get_configuration_for_different_training_types( tmp_path: Path, input_file: Text, expected_file: Text, training_type: TrainingType, ): config_file = str(tmp_path / "config.yml") shutil.copyfile(str(CONFIG_FOLDER / input_file), config_file) config = rasa.shared.utils.io.read_model_configuration(config_file) DefaultV1Recipe.auto_configure(config_file, config, training_type) actual = rasa.shared.utils.io.read_file(config_file) expected = rasa.shared.utils.io.read_file( str(CONFIG_FOLDER / expected_file)) assert actual == expected
def test_nlu_do_not_raise_if_two_tokenizers_with_end_to_end(): config = rasa.shared.utils.io.read_yaml_file( "rasa/engine/recipes/config_files/default_config.yml") graph_config = DefaultV1Recipe().graph_config_for_recipe( config, cli_parameters={}, training_type=TrainingType.END_TO_END) importer = DummyImporter() validator = DefaultV1RecipeValidator(graph_config.train_schema) # Does not raise validator.validate(importer)
def test_nlu_do_not_raise_if_trainable_tokenizer(): config = rasa.shared.utils.io.read_yaml_file( "data/test_config/config_pretrained_embeddings_mitie_zh.yml") graph_config = DefaultV1Recipe().graph_config_for_recipe(config, cli_parameters={}) importer = DummyImporter() validator = DefaultV1RecipeValidator(graph_config.train_schema) # Does not raise validator.validate(importer)
def test_get_configuration(config_path: Path, expected_keys_to_configure: Set[Text], tmp_path: Path): new_config_file = tmp_path / "new_config.yml" shutil.copyfile(config_path, new_config_file) config = rasa.shared.utils.io.read_model_configuration(new_config_file) _config, _missing_keys, configured_keys = DefaultV1Recipe.auto_configure( new_config_file, config) assert sorted(configured_keys) == sorted(expected_keys_to_configure)
def test_no_warnings_with_default_project(tmp_path: Path): rasa.utils.common.copy_directory(Path("rasa/cli/initial_project"), tmp_path) importer = TrainingDataImporter.load_from_config( config_path=str(tmp_path / "config.yml"), domain_path=str(tmp_path / "domain.yml"), training_data_paths=[str(tmp_path / "data")], ) config, _missing_keys, _configured_keys = DefaultV1Recipe.auto_configure( importer.get_config_file_for_auto_config(), importer.get_config(), TrainingType.END_TO_END, ) graph_config = DefaultV1Recipe().graph_config_for_recipe( config, cli_parameters={}, training_type=TrainingType.END_TO_END) validator = DefaultV1RecipeValidator(graph_config.train_schema) with pytest.warns(None) as records: validator.validate(importer) assert len(records) == 0
def test_comment_causing_invalid_autoconfig(tmp_path: Path): """Regression test for https://github.com/RasaHQ/rasa/issues/6948.""" config_file = tmp_path / "config.yml" shutil.copyfile( str(CONFIG_FOLDER / "config_with_comment_between_suggestions.yml"), config_file) config = rasa.shared.utils.io.read_model_configuration(config_file) _ = DefaultV1Recipe.auto_configure(str(config_file), config) # This should not throw dumped = rasa.shared.utils.io.read_yaml_file(config_file) assert dumped
def test_auto_configure(language: Text, keys_to_configure: Set[Text]): expected_config = rasa.shared.utils.io.read_config_file(DEFAULT_CONFIG) config = DefaultV1Recipe.complete_config({"language": language}, keys_to_configure) for k in keys_to_configure: assert config[k] == expected_config[ k] # given keys are configured correctly assert config.get("language") == language config.pop("language") assert len(config) == len( keys_to_configure) # no other keys are configured
def test_retrieve_via_module_path(): model_config = DefaultV1Recipe().graph_config_for_recipe( {"policies": [{ "name": "rasa.core.policies.ted_policy.TEDPolicy" }]}, {}, TrainingType.CORE, ) assert any( issubclass(node.uses, TEDPolicy) for node in model_config.train_schema.nodes.values()) assert any( issubclass(node.uses, TEDPolicy) for node in model_config.predict_schema.nodes.values())