def __init__(self, section_name="bot"): self._brain_config = BrainConfiguration("brain") self._brain_selector = None self._bot_root = BotConfiguration.DEFAULT_ROOT self._default_response = BotConfiguration.DEFAULT_RESPONSE self._default_response_srai = BotConfiguration.DEFAULT_RESPONSE_SRAI self._exit_response = BotConfiguration.DEFAULT_EXIT_RESPONSE self._exit_response_srai = BotConfiguration.DEFAULT_EXIT_RESPONSE_SRAI self._initial_question = BotConfiguration.DEFAULT_INITIAL_QUESTION self._initial_question_srai = BotConfiguration.DEFAULT_INITIAL_QUESTION_SRAI self._empty_string = BotConfiguration.DEFAULT_EMPTY_STRING self._override_properties = BotConfiguration.DEFAULT_OVERRIDE_PREDICATES self._max_question_recursion = BotConfiguration.DEFAULT_MAX_QUESTION_RECURSION self._max_question_timeout = BotConfiguration.DEFAULT_MAX_QUESTION_TIMEOUT self._max_search_depth = BotConfiguration.DEFAULT_MAX_SEARCH_DEPTH self._max_search_timeout = BotConfiguration.DEFAULT_MAX_SEARCH_TIMEOUT self._tab_parse_output = BotConfiguration.DEFAULT_TAB_PARSE_OUTPUT self._rephrase_sentences_file = BotConfiguration.DEFAULT_REPHRASE_FILE self._emotive = BotConfiguration.DEFAULT_EMOTIVE self._spelling = BotSpellingConfiguration() self._conversations = BotConversationsConfiguration() self._session = BotSessionConfiguration() super().__init__(section_name)
def test_brain_init_with_secure_config(self): yaml = YamlConfigurationFile() self.load_os_specific_configuration(yaml, "test_secure_brain.yaml", "test_secure_brain.windows.yaml") brain_config = BrainConfiguration() brain_config.load_configuration(yaml, os.path.dirname(__file__)) brain = Brain(None, brain_config) self.assertIsNotNone(brain) self.assertIsNotNone(brain.aiml_parser) self.assertIsNotNone(brain.denormals) self.assertIsNotNone(brain.normals) self.assertIsNotNone(brain.genders) self.assertIsNotNone(brain.persons) self.assertIsNotNone(brain.person2s) self.assertIsNotNone(brain.properties) self.assertIsNotNone(brain.rdf) self.assertIsNotNone(brain.sets) self.assertIsNotNone(brain.maps) self.assertIsNotNone(brain.preprocessors) self.assertIsNotNone(brain.postprocessors) self.assertIsNotNone(brain.authentication) self.assertIsNotNone(brain.authorisation) self.assertIsNone(brain.default_oob) self.assertEquals({}, brain.oobs)
def test_format_message_with_client_and_bot_and_brain(self): brain_config = BrainConfiguration() brain_config._section_name = "testbrain" brain = Brain(None, brain_config) msg = YLogger.format_message(brain, "Test Message") self.assertIsNotNone(msg) self.assertEquals("[] [] [testbrain] - Test Message", msg)
def test_oob_processing(self): yaml = YamlConfigurationFile() self.load_os_specific_configuration(yaml, "test_brain.yaml", "test_brain.windows.yaml") brain_config = BrainConfiguration() brain_config.load_configuration(yaml, ".") brain = Brain(None, brain_config) self.assertEqual("", brain.process_oob("console", "<oob></oob>"))
def test_oob_loading(self): yaml = YamlConfigurationFile() self.load_os_specific_configuration(yaml, "test_brain.yaml", "test_brain.windows.yaml") brain_config = BrainConfiguration() brain_config.load_configuration(yaml, ".") brain = Brain(None, brain_config) self.assertIsInstance(brain.default_oob, DefaultOutOfBandProcessor) self.assertIsInstance(brain.oobs['dial'], DialOutOfBandProcessor) self.assertIsInstance(brain.oobs['email'], EmailOutOfBandProcessor)
def test_format_message_with_client_and_bot_and_brain(self): client = TestClient() bot_config = BotConfiguration() bot_config._section_name = "testbot" bot = Bot(bot_config, client) brain_config = BrainConfiguration() brain_config._section_name = "testbrain" brain = Brain(bot, brain_config) msg = YLogger.format_message(brain, "Test Message") self.assertIsNotNone(msg) self.assertEquals("[testclient] [testbot] [testbrain] - Test Message", msg)
def test_brain_init_with_config(self): yaml = YamlConfigurationFile() self.load_os_specific_configuration(yaml, "test_brain.yaml", "test_brain.windows.yaml") brain_config = BrainConfiguration() brain_config.load_configuration(yaml, ".") brain = Brain(None, brain_config) self.assertIsNotNone(brain) self.assertIsNotNone(brain.aiml_parser) self.assertIsNotNone(brain.denormals) self.assertIsNotNone(brain.normals) self.assertIsNotNone(brain.genders) self.assertIsNotNone(brain.persons) self.assertIsNotNone(brain.person2s) self.assertIsNotNone(brain.properties) self.assertIsNotNone(brain.rdf) self.assertIsNotNone(brain.sets) self.assertIsNotNone(brain.maps) self.assertIsNotNone(brain.preprocessors) self.assertIsNotNone(brain.postprocessors) self.assertIsNotNone(brain.authentication) self.assertIsNotNone(brain.authorisation) self.assertIsNotNone(brain.default_oob) self.assertIsNotNone(brain.oobs) if os.path.exists(brain_config.binaries.binary_filename): os.remove(brain_config.binaries.binary_filename) self.assertFalse(os.path.exists(brain_config.binaries.binary_filename)) brain.save_binary(brain_config) self.assertTrue(os.path.exists(brain_config.binaries.binary_filename)) brain.load_binary(brain_config) oob_content = ET.fromstring("<oob><something>other</something></oob>") self.assertEqual( "", brain.default_oob.process_out_of_bounds(self._client_context, oob_content)) oob_content = ET.fromstring("<oob><dial>07777777777</dial></oob>") self.assertEqual( "", brain.oobs['dial'].process_out_of_bounds(self._client_context, oob_content))
def get_brain_config(self): brain_config = BrainConfiguration() brain_config.security._authorisation = BrainSecurityConfiguration( "authorisation") brain_config.security.authorisation._classname = "programr.security.authorise.usergroupsauthorisor.BasicUserGroupAuthorisationService" brain_config.security.authorisation._denied_srai = "ACCESS_DENIED" brain_config.security.authorisation._usergroups = "$BOT_ROOT/usergroups.yaml" return brain_config
def load_configurations(self, configuration_file, bot, bot_root): if bot is not None: #brain_names = configuration_file.get_multi_option(bot, "brain", missing_value="brain") brain_name = configuration_file.get_option(bot, "brain", missing_value="brain") config = BrainConfiguration(brain_name) self._brain_config = config config.load_configuration(configuration_file, bot_root) else: YLogger.warning( self, "No brain name defined for bot [%s], defaulting to 'brain'.", self.section_name) brain_name = "brain" self._brain_config._section_name = brain_name self._brain_config.load_configuration(configuration_file, bot_root)
def test_format_message_with_client_context(self): client = TestClient() bot_config = BotConfiguration() bot_config._section_name = "testbot" bot = Bot(bot_config, client) brain_config = BrainConfiguration() brain_config._section_name = "testbrain" brain = Brain(bot, brain_config) client_context = ClientContext(client, "testuser") client_context._bot = bot client_context._brain = brain msg = YLogger.format_message(client_context, "Test Message") self.assertIsNotNone(msg) self.assertEquals( "[testclient] [testbot] [testbrain] [testuser] - Test Message", msg)
def test_load_services(self): service_config = BrainServiceConfiguration("mock") service_config._classname = 'programrtest.services.test_service.MockService' brain_config = BrainConfiguration() brain_config.services._services['mock'] = service_config ServiceFactory.preload_services(brain_config.services) self.assertIsNotNone(ServiceFactory.get_service("mock")) self.assertIsInstance(ServiceFactory.get_service("mock"), MockService)
def test_oob_stripping(self): yaml = YamlConfigurationFile() self.load_os_specific_configuration(yaml, "test_brain.yaml", "test_brain.windows.yaml") brain_config = BrainConfiguration() brain_config.load_configuration(yaml, ".") brain = Brain(None, brain_config) response, oob = brain.strip_oob("<oob>command</oob>") self.assertEqual("", response) self.assertEqual("<oob>command</oob>", oob) response, oob = brain.strip_oob("This <oob>command</oob>") self.assertEqual("This ", response) self.assertEqual("<oob>command</oob>", oob) response, oob = brain.strip_oob("This <oob>command</oob> That") self.assertEqual("This That", response) self.assertEqual("<oob>command</oob>", oob)
def test_brain_init_no_config(self): brain = Brain(None, BrainConfiguration()) self.assertIsNotNone(brain) self.assertIsNotNone(brain.aiml_parser) self.assertIsNotNone(brain.denormals) self.assertIsNotNone(brain.normals) self.assertIsNotNone(brain.genders) self.assertIsNotNone(brain.persons) self.assertIsNotNone(brain.person2s) self.assertIsNotNone(brain.properties) self.assertIsNotNone(brain.rdf) self.assertIsNotNone(brain.sets) self.assertIsNotNone(brain.maps) self.assertIsNotNone(brain.preprocessors) self.assertIsNotNone(brain.postprocessors) self.assertIsNone(brain.default_oob) self.assertIsNotNone(brain.oobs)
def test_call_service(self): service_config = BrainServiceConfiguration("mock") service_config._classname = 'programrtest.services.test_service.MockService' brain_config = BrainConfiguration() brain_config.services._services['mock'] = service_config ServiceFactory.preload_services(brain_config.services) root = TemplateNode() node = TemplateSRAIXNode() node.service = "mock" root.append(node) node.append(TemplateWordNode("Hello")) self.assertEqual("asked", node.resolve(self._client_context))
def get_brain_config(self): return BrainConfiguration()
def test_with_data(self): yaml = YamlConfigurationFile() self.assertIsNotNone(yaml) yaml.load_from_text(""" brain: overrides: allow_system_aiml: true allow_learn_aiml: true allow_learnf_aiml: true defaults: default-get: unknown default-property: unknown default-map: unknown learnf-path: /tmp/learnf nodes: pattern_nodes: $BOT_ROOT/config/pattern_nodes.conf template_nodes: $BOT_ROOT/config/template_nodes.conf binaries: save_binary: false load_binary: false binary_filename: /tmp/y-bot.brain load_aiml_on_binary_fail: false braintree: file: /tmp/braintree.xml content: xml files: aiml: files: $BOT_ROOT/aiml extension: .aiml directories: true errors: /tmp/y-bot_errors.txt duplicates: /tmp/y-bot_duplicates.txt conversation: /tmp/y-bot_conversation.txt sets: files: $BOT_ROOT/sets extension: .txt directories: false maps: files: $BOT_ROOT/maps extension: .txt directories: false denormal: $BOT_ROOT/config/denormal.txt normal: $BOT_ROOT/config/normal.txt gender: $BOT_ROOT/config/gender.txt person: $BOT_ROOT/config/person.txt person2: $BOT_ROOT/config/person2.txt properties: $BOT_ROOT/config/properties.txt triples: $BOT_ROOT/config/triples.txt preprocessors: $BOT_ROOT/config/preprocessors.conf postprocessors: $BOT_ROOT/config/postprocessors.conf regex_templates: $BOT_ROOT/config/regex-templates.txt security: authentication: classname: programr.security.authenticate.passthrough.PassThroughAuthenticationService denied_srai: AUTHENTICATION_FAILED authorisation: classname: programr.security.authorise.passthrough.PassThroughAuthorisationService denied_srai: AUTHORISATION_FAILED oob: default: classname: programr.oob.default.DefaultOutOfBandProcessor dial: classname: programr.oob.dial.DialOutOfBandProcessor email: classname: programr.oob.email.EmailOutOfBandProcessor dynamic: variables: gettime: programr.dynamic.variables.datetime.GetTime sets: number: programr.dynamic.sets.numeric.IsNumeric roman: programr.dynamic.sets.roman.IsRomanNumeral maps: romantodec: programr.dynamic.maps.roman.MapRomanToDecimal dectoroman: programr.dynamic.maps.roman.MapDecimalToRoman services: REST: classname: programr.services.rest.GenericRESTService method: GET host: 0.0.0.0 Pannous: classname: programr.services.pannous.PannousService url: http://weannie.pannous.com/api Pandora: classname: programr.services.pandora.PandoraService url: http://www.pandorabots.com/pandora/talk-xml Wikipedia: classname: programr.services.wikipediaservice.WikipediaService """, ConsoleConfiguration(), ".") brain_config = BrainConfiguration() brain_config.load_configuration(yaml, ".") self.assertIsNotNone(brain_config.overrides) self.assertTrue(brain_config.overrides.allow_system_aiml) self.assertTrue(brain_config.overrides.allow_learn_aiml) self.assertTrue(brain_config.overrides.allow_learnf_aiml) self.assertIsNotNone(brain_config.defaults) self.assertEqual("unknown", brain_config.defaults.default_get) self.assertEqual("unknown", brain_config.defaults.default_property) self.assertEqual("unknown", brain_config.defaults.default_map) self.assertEqual("/tmp/learnf", brain_config.defaults.learnf_path) self.assertIsNotNone(brain_config.nodes) self.assertEquals("./config/pattern_nodes.conf", brain_config.nodes.pattern_nodes) self.assertEquals("./config/template_nodes.conf", brain_config.nodes.template_nodes) self.assertIsNotNone(brain_config.binaries) self.assertFalse(brain_config.binaries.save_binary) self.assertFalse(brain_config.binaries.load_binary) self.assertEquals("/tmp/y-bot.brain", brain_config.binaries.binary_filename) self.assertFalse(brain_config.binaries.load_aiml_on_binary_fail) self.assertIsNotNone(brain_config.braintree) self.assertEquals("/tmp/braintree.xml", brain_config.braintree.file) self.assertEquals("xml", brain_config.braintree.content) self.assertIsNotNone(brain_config.files) self.assertIsNotNone(brain_config.files.aiml_files) self.assertEqual(["./aiml"], brain_config.files.aiml_files.files) self.assertEqual(".aiml", brain_config.files.aiml_files.extension) self.assertTrue(brain_config.files.aiml_files.directories) self.assertEqual("/tmp/y-bot_errors.txt", brain_config.files.aiml_files.errors.filename) self.assertEqual("/tmp/y-bot_duplicates.txt", brain_config.files.aiml_files.duplicates.filename) self.assertEqual("/tmp/y-bot_conversation.txt", brain_config.files.aiml_files.conversation.filename) self.assertIsNotNone(brain_config.files.set_files) self.assertEqual(["./sets"], brain_config.files.set_files.files) self.assertEqual(".txt", brain_config.files.set_files.extension) self.assertFalse(brain_config.files.set_files.directories) self.assertIsNotNone(brain_config.files.map_files) self.assertEqual(["./maps"], brain_config.files.map_files.files) self.assertEqual(".txt", brain_config.files.map_files.extension) self.assertFalse(brain_config.files.map_files.directories) self.assertEqual(brain_config.files.denormal, "./config/denormal.txt") self.assertEqual(brain_config.files.normal, "./config/normal.txt") self.assertEqual(brain_config.files.gender, "./config/gender.txt") self.assertEqual(brain_config.files.person, "./config/person.txt") self.assertEqual(brain_config.files.person2, "./config/person2.txt") self.assertEqual(brain_config.files.properties, "./config/properties.txt") self.assertEqual(brain_config.files.triples, "./config/triples.txt") self.assertEqual(brain_config.files.preprocessors, "./config/preprocessors.conf") self.assertEqual(brain_config.files.postprocessors, "./config/postprocessors.conf") self.assertEqual(brain_config.files.regex_templates, "./config/regex-templates.txt") self.assertIsNotNone(brain_config.security) self.assertIsNotNone(brain_config.security.authorisation) self.assertIsNotNone(brain_config.security.authentication) self.assertIsNotNone(brain_config.services) self.assertTrue(brain_config.services.exists("REST")) self.assertTrue(brain_config.services.exists("Pannous")) self.assertTrue(brain_config.services.exists("Pandora")) self.assertTrue(brain_config.services.exists("Wikipedia")) self.assertFalse(brain_config.services.exists("Other")) self.assertIsNotNone(brain_config.oob) self.assertIsNotNone(brain_config.oob.oobs()) self.assertIsNotNone(brain_config.oob.default()) self.assertIsNotNone(brain_config.oob.oob("dial")) self.assertIsNotNone(brain_config.oob.oob("email")) self.assertIsNotNone(brain_config.dynamics) self.assertIsNotNone(brain_config.dynamics.dynamic_sets) self.assertTrue("NUMBER" in brain_config.dynamics.dynamic_sets) self.assertTrue("ROMAN" in brain_config.dynamics.dynamic_sets) self.assertIsNotNone(brain_config.dynamics.dynamic_maps) self.assertTrue("ROMANTODEC" in brain_config.dynamics.dynamic_maps) self.assertTrue("DECTOROMAN" in brain_config.dynamics.dynamic_maps) self.assertIsNotNone(brain_config.dynamics.dynamic_vars) self.assertTrue("GETTIME" in brain_config.dynamics.dynamic_vars)
class BotConfiguration(BaseContainerConfigurationData): DEFAULT_ROOT = "." DEFAULT_RESPONSE = "" DEFAULT_RESPONSE_SRAI = "" DEFAULT_EMPTY_STRING = "" DEFAULT_EXIT_RESPONSE = "Bye!" DEFAULT_EXIT_RESPONSE_SRAI = "" DEFAULT_INITIAL_QUESTION = "Hello" DEFAULT_INITIAL_QUESTION_SRAI = "" DEFAULT_OVERRIDE_PREDICATES = True DEFAULT_MAX_QUESTION_RECURSION = 100 DEFAULT_MAX_QUESTION_TIMEOUT = -1 DEFAULT_MAX_SEARCH_DEPTH = 100 DEFAULT_MAX_SEARCH_TIMEOUT = -1 DEFAULT_TAB_PARSE_OUTPUT = True DEFAULT_REPHRASE_FILE = None DEFAULT_EMOTIVE = True def __init__(self, section_name="bot"): self._brain_config = BrainConfiguration("brain") self._brain_selector = None self._bot_root = BotConfiguration.DEFAULT_ROOT self._default_response = BotConfiguration.DEFAULT_RESPONSE self._default_response_srai = BotConfiguration.DEFAULT_RESPONSE_SRAI self._exit_response = BotConfiguration.DEFAULT_EXIT_RESPONSE self._exit_response_srai = BotConfiguration.DEFAULT_EXIT_RESPONSE_SRAI self._initial_question = BotConfiguration.DEFAULT_INITIAL_QUESTION self._initial_question_srai = BotConfiguration.DEFAULT_INITIAL_QUESTION_SRAI self._empty_string = BotConfiguration.DEFAULT_EMPTY_STRING self._override_properties = BotConfiguration.DEFAULT_OVERRIDE_PREDICATES self._max_question_recursion = BotConfiguration.DEFAULT_MAX_QUESTION_RECURSION self._max_question_timeout = BotConfiguration.DEFAULT_MAX_QUESTION_TIMEOUT self._max_search_depth = BotConfiguration.DEFAULT_MAX_SEARCH_DEPTH self._max_search_timeout = BotConfiguration.DEFAULT_MAX_SEARCH_TIMEOUT self._tab_parse_output = BotConfiguration.DEFAULT_TAB_PARSE_OUTPUT self._rephrase_sentences_file = BotConfiguration.DEFAULT_REPHRASE_FILE self._emotive = BotConfiguration.DEFAULT_EMOTIVE self._spelling = BotSpellingConfiguration() self._conversations = BotConversationsConfiguration() self._session = BotSessionConfiguration() super().__init__(section_name) def load_configuration(self, configuration_file, bot_root): bot = configuration_file.get_section(self.section_name) if bot is not None: self._default_response = configuration_file.get_option( bot, "default_response", BotConfiguration.DEFAULT_RESPONSE) self._default_response_srai = configuration_file.get_option( bot, "default_response_srai", BotConfiguration.DEFAULT_RESPONSE_SRAI) self._empty_string = configuration_file.get_option( bot, "empty_string", BotConfiguration.DEFAULT_EMPTY_STRING) self._exit_response = configuration_file.get_option( bot, "exit_response", BotConfiguration.DEFAULT_EXIT_RESPONSE) self._exit_response_srai = configuration_file.get_option( bot, "exit_response_srai", BotConfiguration.DEFAULT_EXIT_RESPONSE_SRAI) self._initial_question = configuration_file.get_option( bot, "initial_question", BotConfiguration.DEFAULT_INITIAL_QUESTION) self._initial_question_srai = configuration_file.get_option( bot, "initial_question_srai", BotConfiguration.DEFAULT_INITIAL_QUESTION_SRAI) self._override_properties = configuration_file.get_option( bot, "override_properties", BotConfiguration.DEFAULT_OVERRIDE_PREDICATES) self._max_question_recursion = configuration_file.get_int_option( bot, "max_question_recursion", BotConfiguration.DEFAULT_MAX_QUESTION_RECURSION) self._max_question_timeout = configuration_file.get_int_option( bot, "max_question_timeout", BotConfiguration.DEFAULT_MAX_QUESTION_TIMEOUT) self._max_search_depth = configuration_file.get_int_option( bot, "max_search_depth", BotConfiguration.DEFAULT_MAX_SEARCH_DEPTH) self._max_search_timeout = configuration_file.get_int_option( bot, "max_search_timeout", BotConfiguration.DEFAULT_MAX_SEARCH_TIMEOUT) self._tab_parse_output = configuration_file.get_bool_option( bot, "tab_parse_output", BotConfiguration.DEFAULT_TAB_PARSE_OUTPUT) self._rephrase_sentences_file = configuration_file.get_option( bot, "rephrase_sentences_file", BotConfiguration.DEFAULT_REPHRASE_FILE) self._emotive = configuration_file.get_bool_option( bot, "emotive", BotConfiguration.DEFAULT_EMOTIVE) self._spelling.load_config_section(configuration_file, bot, bot_root) self._conversations.load_config_section(configuration_file, bot, bot_root) self._session.load_config_section(configuration_file, bot, bot_root) else: YLogger.warning( self, "Config section [%s] missing, using default values", self.section_name) self.load_configurations(configuration_file, bot, bot_root) def load_configurations(self, configuration_file, bot, bot_root): if bot is not None: #brain_names = configuration_file.get_multi_option(bot, "brain", missing_value="brain") brain_name = configuration_file.get_option(bot, "brain", missing_value="brain") config = BrainConfiguration(brain_name) self._brain_config = config config.load_configuration(configuration_file, bot_root) else: YLogger.warning( self, "No brain name defined for bot [%s], defaulting to 'brain'.", self.section_name) brain_name = "brain" self._brain_config._section_name = brain_name self._brain_config.load_configuration(configuration_file, bot_root) @property def brain_config(self): return self._brain_config @property def bot_root(self): return self._bot_root @property def default_response(self): return self._default_response @default_response.setter def default_response(self, text): self._default_response = text @property def default_response_srai(self): return self._default_response_srai @default_response_srai.setter def default_response_srai(self, text): self._default_response_srai = text @property def empty_string(self): return self._empty_string @empty_string.setter def empty_string(self, text): self._empty_string = text @property def exit_response(self): return self._exit_response @exit_response.setter def exit_response(self, text): self._exit_response = text @property def exit_response_srai(self): return self._exit_response_srai @exit_response_srai.setter def exit_response_srai(self, text): self._exit_response_srai = text @property def initial_question(self): return self._initial_question @initial_question.setter def initial_question(self, text): self._initial_question = text @property def initial_question_srai(self): return self._initial_question_srai @initial_question_srai.setter def initial_question_srai(self, text): self._initial_question_srai = text @property def override_properties(self): return self._override_properties @override_properties.setter def override_properties(self, override): self._override_properties = override @property def max_question_recursion(self): return self._max_question_recursion @property def max_question_timeout(self): return self._max_question_timeout @property def max_search_depth(self): return self._max_search_depth @property def max_search_timeout(self): return self._max_search_timeout @property def tab_parse_output(self): return self._tab_parse_output @property def rephrase_clauses_file(self): return self._rephrase_sentences_file @property def emotive(self): return self._emotive @property def spelling(self): return self._spelling @property def conversations(self): return self._conversations @property def session(self): return self._session def to_yaml(self, data, defaults=True): data['bot_root'] = self.bot_root data['default_response'] = self.default_response data['default_response_srai'] = self.default_response_srai data['exit_response'] = self.exit_response data['exit_response_srai'] = self.exit_response_srai data['initial_question'] = self.initial_question data['initial_question_srai'] = self.initial_question_srai data['empty_string'] = self.empty_string data['override_properties'] = self.override_properties data['max_question_recursion'] = self.max_question_recursion data['max_question_timeout'] = self.max_question_timeout data['max_search_depth'] = self.max_search_depth data['max_search_timeout'] = self.max_search_timeout data['tab_parse_output'] = self.tab_parse_output data['rephrase_clauses_file'] = self.rephrase_clauses_file data['emotive'] = self.emotive self.config_to_yaml(data, BotSpellingConfiguration(), defaults) self.config_to_yaml(data, BotConversationsConfiguration(), defaults)