Example #1
0
    def test_load_additionals(self):
        config = JSONConfigurationFile()
        self.assertIsNotNone(config)
        configuration = config.load_from_text(
            """
            {
              "console": {
                "bot": "bot"
              },
              "bot": {
                "brain": "brain"
              },
              "brain": {
                "security": {
                  "authentication": {
                    "classname": "programy.security.authenticate.passthrough.PassThroughAuthenticationService",
                    "denied_srai": "ACCESS_DENIED"
                  }
                }
              }
            }
            """, ConsoleConfiguration(), ".")

        self.assertIsNotNone(configuration)

        auth_service = configuration.client_configuration.configurations[
            0].configurations[0].security.authentication
        self.assertIsNotNone(auth_service)
        self.assertEqual("ACCESS_DENIED", auth_service.denied_srai)
Example #2
0
    def test_load_from_text_multis_multiple_values(self):
        json = JSONConfigurationFile()
        self.assertIsNotNone(json)
        configuration = json.load_from_text(
            """
        {
          "console": {
            "bots": {
              "bot1": {
                "brains": {
                  "brain1": null,
                  "brain2": null
                }
              },
              "bot2": {
                "brains": {
                  "brain3": null
                }
              }
            }
          }
        }""", ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        self.assertEqual(
            2,
            len(configuration.client_configuration.configurations[0].
                configurations))
Example #3
0
    def test_load_with_subs(self):
        subs = Substitutions()
        subs.add_substitute("$ALLOW_SYSTEM", True)

        config_data = JSONConfigurationFile()
        self.assertIsNotNone(config_data)
        configuration = config_data.load_from_text(
            """
{"brain": {
    "overrides": {
          "allow_system_aiml": true,
          "allow_learn_aiml": true,
          "allow_learnf_aiml": true
          }
      }
}
          """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        section = config_data.get_section("brainx")
        self.assertIsNone(section)

        section = config_data.get_section("brain")
        self.assertIsNotNone(section)

        child_section = config_data.get_section("overrides", section)
        self.assertIsNotNone(child_section)

        self.assertEqual(
            True, config_data.get_option(child_section, "allow_system_aiml"))
        self.assertEqual(
            True,
            config_data.get_bool_option(child_section, "allow_system_aiml"))
        self.assertEqual(
            False, config_data.get_bool_option(child_section, "other_value"))
Example #4
0
    def test_load_additionals(self):
        json = JSONConfigurationFile()
        self.assertIsNotNone(json)
        configuration = json.load_from_text(
            """
{
	"console": {
		"bot": "bot"
	},
	"bot": {
		"brain": "brain"
	},
	"brain": {
		"services": {
			"authentication": {
				"classname": "programy.services.authenticate.passthrough.PassThroughAuthenticationService",
				"denied_srai": "ACCESS_DENIED"
			}
		}
	}
}            """, ConsoleConfiguration(), ".")

        self.assertIsNotNone(configuration)

        self.assertTrue(configuration.client_configuration.configurations[0].
                        configurations[0].services.exists("authentication"))
        auth_service = configuration.client_configuration.configurations[
            0].configurations[0].services.service("authentication")
        self.assertIsNotNone(auth_service)

        self.assertTrue(auth_service.exists("denied_srai"))
        self.assertEqual("ACCESS_DENIED", auth_service.value("denied_srai"))
Example #5
0
    def test_load_from_text_multis_one_value(self):
        config = JSONConfigurationFile()
        self.assertIsNotNone(config)
        configuration = config.load_from_text("""
            {
                "bot": {
                    "brain": "bot1"
                }
            }
        """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        self.assertEqual(1, len(configuration.client_configuration.configurations[0].configurations))
Example #6
0
    def test_get_methods(self):
        config_data = JSONConfigurationFile()
        self.assertIsNotNone(config_data)
        configuration = config_data.load_from_text(
            """
        {
        	"brain": {
        		"overrides": {
        			"allow_system_aiml": true,
        			"allow_learn_aiml": true,
        			"allow_learnf_aiml": true,
        			"int_value": 999
        		}
        	}
        }
         """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        section = config_data.get_section("brainx")
        self.assertIsNone(section)

        section = config_data.get_section("brain")
        self.assertIsNotNone(section)

        child_section = config_data.get_section("overrides", section)
        self.assertIsNotNone(child_section)

        keys = list(config_data.get_child_section_keys("overrides", section))
        self.assertIsNotNone(keys)
        self.assertEqual(4, len(keys))
        self.assertTrue("allow_system_aiml" in keys)
        self.assertTrue("allow_learn_aiml" in keys)
        self.assertTrue("allow_learnf_aiml" in keys)
        self.assertIsNone(
            config_data.get_child_section_keys("missing", section))
        self.assertEqual(
            True, config_data.get_option(child_section, "allow_system_aiml"))
        self.assertEqual(
            True,
            config_data.get_option(child_section,
                                   "missing",
                                   missing_value=True))
        self.assertEqual(
            True,
            config_data.get_bool_option(child_section, "allow_system_aiml"))
        self.assertEqual(
            False, config_data.get_bool_option(child_section, "other_value"))
        self.assertEqual(
            999, config_data.get_int_option(child_section, "int_value"))
        self.assertEqual(
            0, config_data.get_int_option(child_section, "other_value"))
Example #7
0
    def test_load_from_text_multi_files(self):
        json = JSONConfigurationFile()
        self.assertIsNotNone(json)
        configuration = json.load_from_text(
            """
        {
        	"brain": {
        		"files": {
        			"aiml": {
        				"files": ["$BOT_ROOT/test-aiml", "/my-aiml/test.aiml"],
        				"extension": ".test-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/test-sets",
        				"extension": ".test-txt",
        				"directories": true
        			},
        			"maps": {
        				"files": "$BOT_ROOT/test-maps",
        				"extension": ".test-txt",
        				"directories": true
        			}
        		}
        	}
        }
                """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        self.assertTrue(
            configuration.client_configuration.configurations[0].
            configurations[0].files.aiml_files.has_multiple_files())
        self.assertFalse(configuration.client_configuration.configurations[0].
                         configurations[0].files.aiml_files.has_single_file())

        self.assertEqual(
            configuration.client_configuration.configurations[0].
            configurations[0].files.aiml_files.files,
            ['./test-aiml', '/my-aiml/test.aiml'])
        self.assertEqual(
            configuration.client_configuration.configurations[0].
            configurations[0].files.set_files.files, ["./test-sets"])
        self.assertEqual(
            configuration.client_configuration.configurations[0].
            configurations[0].files.map_files.files, ["./test-maps"])
Example #8
0
    def test_load_from_text(self):
        json = JSONConfigurationFile()
        self.assertIsNotNone(json)

        text_file = os.path.dirname(__file__) + os.sep + "test_json.json"

        text = ""
        with open(text_file, "r+") as textfile:
            lines = textfile.readlines()
            for line in lines:
                text += line
                text += "\n"

        configuration = json.load_from_text(text, ConsoleConfiguration(), ".")

        self.assertIsNotNone(configuration)
        self.assert_configuration(configuration)
Example #9
0
    def test_load_from_text(self):
        config = JSONConfigurationFile()
        self.assertIsNotNone(config)
        configuration = config.load_from_text(
            """
{
  "console": {
    "bot": "bot",
    "prompt": ">>>",
    "scheduler": {
      "name": "Scheduler1",
      "debug_level": 50,
      "add_listeners": false,
      "remove_all_jobs": false
    },
    "storage": {
      "entities": {
        "users": "sql",
        "linked_accounts": "sql",
        "links": "sql",
        "properties": "file",
        "conversations": "file",
        "categories": "file",
        "maps": "file",
        "sets": "file",
        "rdf": "file",
        "denormal": "file",
        "normal": "file",
        "gender": "file",
        "person": "file",
        "person2": "file",
        "spelling_corpus": "file",
        "license_keys": "file",
        "nodes": "file",
        "binaries": "file",
        "braintree": "file",
        "preprocessors": "file",
        "postprocessors": "file",
        "regex_templates": "file",
        "usergroups": "file",
        "learnf": "file"
      },
      "stores": {
        "sql": {
          "type": "sql",
          "config": {
            "url": "sqlite:///:memory",
            "echo": false,
            "encoding": "utf-8",
            "create_db": true,
            "drop_all_first": true
          }
        },
        "mongo": {
          "type": "mongo",
          "config": {
            "url": "mongodb://localhost:27017/",
            "database": "programy",
            "drop_all_first": true
          }
        },
        "redis": {
          "type": "redis",
          "config": {
            "host": "localhost",
            "port": 6379,
            "password": null,
            "db": 0,
            "prefix": "programy",
            "drop_all_first": true
          }
        },
        "file": {
          "type": "file",
          "config": {
            "category_storage": {
              "files": "./storage/categories"
            },
            "conversations_storage": {
              "files": "./storage/conversations"
            },
            "sets_storage": {
              "files": "./storage/sets",
              "extension": ".txt",
              "directories": false
            },
            "maps_storage": {
              "files": "./storage/maps",
              "extension": ".txt",
              "directories": false
            },
            "regex_templates": {
              "files": "./storage/regex"
            },
            "lookups_storage": {
              "files": "./storage/lookups",
              "extension": ".txt",
              "directories": false
            },
            "properties_storage": {
              "file": "./storage/properties.txt"
            },
            "defaults_storage": {
              "file": "./storage/defaults.txt"
            },
            "rdf_storage": {
              "files": "./storage/rdfs",
              "extension": ".txt",
              "directories": true
            },
            "spelling_corpus": {
              "file": "./storage/spelling/corpus.txt"
            },
            "license_keys": {
              "file": "./storage/license.keys"
            },
            "nodes": {
              "files": "./storage/nodes"
            },
            "binaries": {
              "files": "./storage/binaries"
            },
            "braintree": {
              "file": "./storage/braintree/braintree.xml",
              "format": "xml"
            },
            "preprocessors": {
              "file": "./storage/processing/preprocessors.txt"
            },
            "postprocessors": {
              "file": "./storage/processing/postprocessing.txt"
            },
            "usergroups": {
              "files": "./storage/security/usergroups.txt"
            },
            "learnf": {
              "files": "./storage/categories/learnf"
            }
          }
        }
      }
    },
    "logger": {
      "type": "logger",
      "config": {
        "conversation_logger": "conversation"
      }
    }
  },
  "voice": {
    "license_keys": "$BOT_ROOT/config/license.keys",
    "tts": "osx",
    "stt": "azhang",
    "osx": {
      "classname": "talky.clients.voice.tts.osxsay.OSXSayTextToSpeach"
    },
    "pytts": {
      "classname": "talky.clients.voice.tts.pyttssay.PyTTSSayTextToSpeach",
      "rate_adjust": 10
    },
    "azhang": {
      "classname": "talky.clients.voice.stt.azhang.AnthonyZhangSpeechToText",
      "ambient_adjust": 3,
      "service": "ibm"
    }
  },
  "rest": {
    "host": "0.0.0.0",
    "port": 8989,
    "debug": false,
    "workers": 4,
    "license_keys": "$BOT_ROOT/config/license.keys"
  },
  "webchat": {
    "host": "0.0.0.0",
    "port": 8090,
    "debug": false,
    "license_keys": "$BOT_ROOT/config/license.keys",
    "api": "/api/web/v1.0/ask"
  },
  "twitter": {
    "polling": true,
    "polling_interval": 49,
    "streaming": false,
    "use_status": true,
    "use_direct_message": true,
    "auto_follow": true,
    "storage": "file",
    "welcome_message": "Thanks for following me, send me a message and I'll try and help",
    "license_keys": "file"
  },
  "xmpp": {
    "server": "talk.google.com",
    "port": 5222,
    "xep_0030": true,
    "xep_0004": true,
    "xep_0060": true,
    "xep_0199": true,
    "license_keys": "file"
  },
  "socket": {
    "host": "127.0.0.1",
    "port": 9999,
    "queue": 5,
    "debug": true,
    "license_keys": "file"
  },
  "telegram": {
    "unknown_command": "Sorry, that is not a command I have been taught yet!",
    "license_keys": "file"
  },
  "facebook": {
    "host": "127.0.0.1",
    "port": 5000,
    "debug": false,
    "license_keys": "file"
  },
  "twilio": {
    "host": "127.0.0.1",
    "port": 5000,
    "debug": false,
    "license_keys": "file"
  },
  "slack": {
    "polling_interval": 1,
    "license_keys": "file"
  },
  "viber": {
    "name": "Servusai",
    "avatar": "http://viber.com/avatar.jpg",
    "license_keys": "file"
  },
  "line": {
    "host": "127.0.0.1",
    "port": 8084,
    "debug": false,
    "license_keys": "file"
  },
  "kik": {
    "bot_name": "servusai",
    "webhook": "https://93638f7a.ngrok.io/api/kik/v1.0/ask",
    "host": "127.0.0.1",
    "port": 8082,
    "debug": false,
    "license_keys": "file"
  },
  "bot": {
    "brain": "brain",
    "initial_question": "Hi, how can I help you today?",
    "initial_question_srai": "YINITIALQUESTION",
    "default_response": "Sorry, I don't have an answer for that!",
    "default_response_srai": "YEMPTY",
    "empty_string": "YEMPTY",
    "exit_response": "So long, and thanks for the fish!",
    "exit_response_srai": "YEXITRESPONSE",
    "override_properties": true,
    "max_question_recursion": 1000,
    "max_question_timeout": 60,
    "max_search_depth": 100,
    "max_search_timeout": 60,
    "spelling": {
      "load": true,
      "classname": "programy.spelling.norvig.NorvigSpellingChecker",
      "check_before": true,
      "check_and_retry": true
    },
    "conversations": {
      "max_histories": 100,
      "restore_last_topic": false,
      "initial_topic": "TOPIC1",
      "empty_on_start": false
    }
  },
  "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": "file"
    },
    "binaries": {
      "save_binary": true,
      "load_binary": true,
      "load_aiml_on_binary_fail": true
    },
    "braintree": {
      "create": true
    },
    "services": {
      "REST": {
        "classname": "programy.services.rest.GenericRESTService",
        "method": "GET",
        "host": "0.0.0.0",
        "port": 8080
      },
      "Pannous": {
        "classname": "programy.services.pannous.PannousService",
        "url": "http://weannie.pannous.com/api"
      }
    },
    "security": {
      "authentication": {
        "classname": "programy.security.authenticate.passthrough.BasicPassThroughAuthenticationService",
        "denied_srai": "AUTHENTICATION_FAILED"
      },
      "authorisation": {
        "classname": "programy.security.authorise.usergroupsauthorisor.BasicUserGroupAuthorisationService",
        "denied_srai": "AUTHORISATION_FAILED",
        "usergroups": {
          "storage": "file"
        }
      }
    },
    "oob": {
      "default": {
        "classname": "programy.oob.defaults.default.DefaultOutOfBandProcessor"
      },
      "alarm": {
        "classname": "programy.oob.defaults.alarm.AlarmOutOfBandProcessor"
      },
      "camera": {
        "classname": "programy.oob.defaults.camera.CameraOutOfBandProcessor"
      },
      "clear": {
        "classname": "programy.oob.defaults.clear.ClearOutOfBandProcessor"
      },
      "dial": {
        "classname": "programy.oob.defaults.dial.DialOutOfBandProcessor"
      },
      "dialog": {
        "classname": "programy.oob.defaults.dialog.DialogOutOfBandProcessor"
      },
      "email": {
        "classname": "programy.oob.defaults.email.EmailOutOfBandProcessor"
      },
      "geomap": {
        "classname": "programy.oob.defaults.map.MapOutOfBandProcessor"
      },
      "schedule": {
        "classname": "programy.oob.defaults.schedule.ScheduleOutOfBandProcessor"
      },
      "search": {
        "classname": "programy.oob.defaults.search.SearchOutOfBandProcessor"
      },
      "sms": {
        "classname": "programy.oob.defaults.sms.SMSOutOfBandProcessor"
      },
      "url": {
        "classname": "programy.oob.defaults.url.URLOutOfBandProcessor"
      },
      "wifi": {
        "classname": "programy.oob.defaults.wifi.WifiOutOfBandProcessor"
      }
    },
    "dynamic": {
      "variables": {
        "gettime": "programy.dynamic.variables.datetime.GetTime"
      },
      "sets": {
        "numeric": "programy.dynamic.sets.numeric.IsNumeric",
        "roman": "programy.dynamic.sets.roman.IsRomanNumeral"
      },
      "maps": {
        "romantodec": "programy.dynamic.maps.roman.MapRomanToDecimal",
        "dectoroman": "programy.dynamic.maps.roman.MapDecimalToRoman"
      }
    }
  }
}
            """, ConsoleConfiguration(), ".")

        self.assertIsNotNone(configuration)
        self.assert_configuration(configuration)
Example #10
0
    def test_get_invalid_values(self):
        config_data = JSONConfigurationFile()
        self.assertIsNotNone(config_data)
        configuration = config_data.load_from_text(
            """
        {"section1": {
            "section2": {
                  "boolvalue": true,
                  "intvalue": 23,
                  "strvalue": "hello",
                  "multivalue": [ "one", "two", "three" ]
                  }
              }
        }
                  """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)

        section = config_data.get_section("section1")
        self.assertIsNotNone(section)

        child_section = config_data.get_section("section2", section)
        self.assertIsNotNone(child_section)

        self.assertEquals(
            1, config_data.get_int_option(child_section, "boolvalue"))
        self.assertEquals(
            23, config_data.get_int_option(child_section, "intvalue"))
        self.assertEquals(
            0, config_data.get_int_option(child_section, "strvalue"))

        self.assertTrue(config_data.get_bool_option(child_section,
                                                    "boolvalue"))
        self.assertTrue(config_data.get_bool_option(child_section, "intvalue"))
        self.assertTrue(config_data.get_bool_option(child_section, "strvalue"))

        self.assertEquals(['one', 'two', 'three'],
                          config_data.get_multi_option(child_section,
                                                       "multivalue"))
        self.assertEquals([True],
                          config_data.get_multi_option(child_section,
                                                       "boolvalue"))
        self.assertEquals([23],
                          config_data.get_multi_option(child_section,
                                                       "intvalue"))
        self.assertEquals(["hello"],
                          config_data.get_multi_option(child_section,
                                                       "strvalue"))

        self.assertEquals(['one', 'two', 'three'],
                          config_data.get_multi_file_option(
                              child_section, "multivalue", "."))
        self.assertEquals([],
                          config_data.get_multi_file_option(
                              child_section, "boolvalue", "."))
        self.assertEquals([],
                          config_data.get_multi_file_option(
                              child_section, "intvalue", "."))
        self.assertEquals(["hello"],
                          config_data.get_multi_file_option(
                              child_section, "strvalue", "."))

        self.assertEquals([],
                          config_data.get_multi_file_option(
                              child_section, "unknown1", "."))
        self.assertEquals(["missing1", "missing2"],
                          config_data.get_multi_file_option(
                              child_section,
                              "unknown1",
                              ".",
                              missing_value=["missing1", "missing2"]))
Example #11
0
    def test_load_from_text(self):
        json = JSONConfigurationFile()
        self.assertIsNotNone(json)
        configuration = json.load_from_text(
            """
{
	"brain": {
		"overrides": {
			"allow_system_aiml": true,
			"allow_learn_aiml": true,
			"allow_learnf_aiml": true
		},
		"defaults": {
			"default-get": "test_unknown",
			"default-property": "test_unknown",
			"default-map": "test_unknown",
			"learn-filename": "test-learnf.aiml"
		},
		"nodes": {
			"pattern_nodes": "$BOT_ROOT/config/test_pattern_nodes.conf",
			"template_nodes": "$BOT_ROOT/config/test_template_nodes.conf"
		},
		"binaries": {
			"save_binary": true,
			"load_binary": true,
			"binary_filename": "/tmp/y-bot.brain",
			"load_aiml_on_binary_fail": true
		},
        "braintree": {
              "file": "/tmp/braintree.xml",
              "content": "xml"
        },
		"files": {
			"aiml": {
				"files": "$BOT_ROOT/test-aiml",
				"extension": ".test-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/test-sets",
				"extension": ".test-txt",
				"directories": true
			},
			"maps": {
				"files": "$BOT_ROOT/test-maps",
				"extension": ".test-txt",
				"directories": true
			},
			"denormal": "$BOT_ROOT/config/test-denormal.txt",
			"normal": "$BOT_ROOT/config/test-normal.txt",
			"gender": "$BOT_ROOT/config/test-gender.txt",
			"person": "$BOT_ROOT/config/test-person.txt",
			"person2": "$BOT_ROOT/config/test-person2.txt",
			"predicates": "$BOT_ROOT/config/test-predicates.txt",
			"pronouns": "$BOT_ROOT/config/test-pronouns.txt",
			"properties": "$BOT_ROOT/config/test-properties.txt",
			"triples": "$BOT_ROOT/config/test-triples.txt",
			"preprocessors": "$BOT_ROOT/config/test-preprocessors.conf",
			"postprocessors": "$BOT_ROOT/config/test-postprocessors.conf",
			"regex_templates": "$BOT_ROOT/config/regex-templates.txt"
		},
		"services": {
			"REST": {
				"classname": "programy.services.rest.GenericRESTService",
				"method": "GET",
				"host": "0.0.0.0"
			},
			"Pannous": {
				"classname": "programy.services.pannous.PannousService",
				"url": "http://weannie.pannous.com/api"
			},
			"Pandora": {
				"classname": "programy.services.pandora.PandoraService",
				"url": "http://www.pandorabots.com/pandora/talk-xml"
			},
			"Wikipedia": {
				"classname": "programy.services.wikipediaservice.WikipediaService"
			}
		}
	},
	"bot": {
		"license_keys": "$BOT_ROOT/config/test-license.keys",
		"prompt": "TEST>>>",
		"initial_question": "Hi, how can I help you test today?",
		"default_response": "Sorry, I don't have a test answer for that!",
		"empty_string": "TEST-YEMPTY",
		"exit_response": "So long, and thanks for the test fish!",
		"override_properties": true,
        "max_question_recursion": 1000,
        "max_question_timeout": 60,
        "max_search_depth": 100,
        "max_search_timeout": 60,
		"spelling": {
			"classname": "programy.spelling.checker.TestSpellingChecker",
			"corpus": "$BOT_ROOT/spelling/test-corpus.txt",
			"check_before": true,
			"check_and_retry": true
		}
	},
	"rest": {
		"host": "127.0.0.1",
		"port": 5000,
		"debug": false
	},
	"webchat": {
		"host": "127.0.0.1",
		"port": 5000,
		"debug": false
	},
	"twitter": {
		"polling": true,
		"polling_interval": 49,
		"streaming": false,
		"use_status": true,
		"use_direct_message": true,
		"auto_follow": true,
		"storage": "file",
		"storage_location": "$BOT_ROOT/storage/twitter.data",
		"welcome_message": "Thanks for following me, send me a message and I'll try and help"
	},
	"facebook": {
		"polling": false,
		"polling_interval": 30,
		"streaming": true
	},
	"xmpp": {
		"server": "talk.google.com",
		"port": 5222,
		"xep_0030": true,
		"xep_0004": true,
		"xep_0060": true,
		"xep_0199": true
	}
}
        """, ConsoleConfiguration(), ".")
        self.assertIsNotNone(configuration)
        self.assert_configuration(configuration)
Example #12
0
    def test_load_from_text(self):
        client_config = ClientConfiguration()
        json = JSONConfigurationFile(client_config)
        self.assertIsNotNone(json)
        json.load_from_text(
            """
{
    "brain": {
        "supress_warnings": false,
        "allow_system_aiml": true,
        "allow_learn_aiml": true,
        "allow_learnf_aiml": true,

        "files": {
            "aiml": {
                "files": "/aiml",
                "extension": ".aiml",
                "directories": true
            },
            "sets": {
                "files": "/sets",
                "extension": ".txt",
                "directories": false
            },
            "maps": {
                "files": "/maps",
                "extension": ".txt",
                "directories": true
            },
            "denormal": "denormal.txt",
            "normal": "normal.txt",
            "gender": "gender.txt",
            "person": "person.txt",
            "person2": "person2.txt",
            "predicates": "predicates.txt",
            "pronouns": "pronouns.txt",
            "properties": "properties.txt",
            "triples": "triples.txt",
            "preprocessors": "preprocessors.txt",
            "postprocessors": "postprocessors.txt"
        },

        "services": {
            "REST": {
                "path": "programy.utils.services.rest.GenericRESTService"
            },
            "Pannous": {
                "path": "programy.utils.services.pannous.PannousService"
            },
            "Pandora": {
                "path": "programy.utils.services.pandora.PandoraService"
            },
            "Wikipedia": {
                "path": "programy.utils.services.wikipedia.WikipediaService"
            }
        }
    },
    "bot": {
        "prompt": ">>>",
        "default_response": "Sorry, I don't have an answer for that!",
        "exit_response": "So long, and thanks for the fish!",
        "initial_question": "Hi, how can I help you>"
    }
}""", ",")