Эх сурвалжийг харах

Merge pull request #36 from kalliope-project/dev

Dev
Nicolas Marcq 8 жил өмнө
parent
commit
7baec69c96
57 өөрчлөгдсөн 933 нэмэгдсэн , 217 устгасан
  1. 2 1
      Docs/neuron_list.md
  2. 78 9
      core/ConfigurationManager/BrainLoader.py
  3. 138 17
      core/ConfigurationManager/ConfigurationChecker.py
  4. 213 26
      core/ConfigurationManager/SettingLoader.py
  5. 32 5
      core/ConfigurationManager/YAMLLoader.py
  6. 27 7
      core/CrontabManager.py
  7. 29 6
      core/FileManager.py
  8. 14 11
      core/MainController.py
  9. 5 0
      core/Models/Brain.py
  10. 13 0
      core/Models/Event.py
  11. 11 1
      core/Models/Neuron.py
  12. 13 0
      core/Models/Order.py
  13. 4 0
      core/Models/RestAPI.py
  14. 6 0
      core/Models/Settings.py
  15. 2 0
      core/Models/Singleton.py
  16. 5 1
      core/Models/Stt.py
  17. 14 1
      core/Models/Synapse.py
  18. 5 2
      core/Models/Trigger.py
  19. 5 1
      core/Models/Tts.py
  20. 40 16
      core/NeuronModule.py
  21. 1 6
      core/NeuroneLauncher.py
  22. 12 0
      core/OrderAnalyser.py
  23. 16 3
      core/OrderListener.py
  24. 20 5
      core/Players/Mplayer.py
  25. 9 10
      core/ShellGui.py
  26. 5 1
      core/SynapseLauncher.py
  27. 3 0
      core/TTS/TTSLauncher.py
  28. 21 8
      core/TTS/TTSModule.py
  29. 1 2
      core/TriggerLauncher.py
  30. 12 1
      core/Utils.py
  31. 0 2
      kalliope.py
  32. 10 0
      neurons/gmail_checker/gmail_checker.py
  33. 3 0
      neurons/kill_switch/kill_switch.py
  34. 10 2
      neurons/neurotransmitter/neurotransmitter.py
  35. 2 0
      neurons/openweathermap/Openweathermap.py
  36. 4 3
      neurons/push_message/Push_message.py
  37. 2 0
      neurons/say/say.py
  38. 2 0
      neurons/script/script.py
  39. 10 0
      neurons/shell/shell.py
  40. 8 8
      neurons/sleep/sleep.py
  41. 0 3
      neurons/systemdate/systemdate.py
  42. 2 0
      neurons/tasker_autoremote/tasker_autoremote.py
  43. 2 0
      neurons/twitter/Twitter.py
  44. 4 2
      neurons/wake_on_lan/Wake_on_lan.py
  45. 5 2
      neurons/wikipedia/Wikipedia.py
  46. 4 4
      stt/apiai/Apiai.py
  47. 5 4
      stt/bing/Bing.py
  48. 5 4
      stt/google/Google.py
  49. 8 13
      stt/houndify/Houndify.py
  50. 5 4
      stt/wit/Wit.py
  51. 4 20
      test.py
  52. 0 1
      trigger/snowboy/snowboydecoder.py
  53. 24 0
      tts/acapela/acapela.py
  54. 15 0
      tts/googletts/googletts.py
  55. 10 2
      tts/pico2wave/pico2wave.py
  56. 14 1
      tts/voicerss/voicerss.py
  57. 19 2
      tts/voxygen/voxygen.py

+ 2 - 1
Docs/neuron_list.md

@@ -4,7 +4,7 @@ A neuron is a module that will perform some actions attached to an order. You ca
 
 | Name                                               | Description                                                                             | Used to sort      |
 |----------------------------------------------------|-----------------------------------------------------------------------------------------|-------------------|
-| [ansible_task](../neurons/ansible_task/)           | Run an ansible playbook                                                                 | ansible_task      |
+| [ansible_playbook](../neurons/ansible_playbook/)   | Run an ansible playbook                                                                 | ansible_task      |
 | [gmail_checker](../neurons/gmail_checker/)         | Get the number of unread email and their subjects from a gmail account                  | gmail_checker     |
 | [kill_switch](../neurons/kill_switch/)             | Stop Kalliope process                                                                   | kill_switch       |
 | [neurotransmitter](../neurons/neurotransmitter/)   | Link synapse together                                                                   | neurotransmitter  |
@@ -16,5 +16,6 @@ A neuron is a module that will perform some actions attached to an order. You ca
 | [systemdate](../neurons/systemdate/)               | Give the local system date and time                                                     | systemdate        |
 | [tasker_autoremote](../neurons/tasker_autoremote/) | Send a message to Android tasker app                                                    | tasker_autoremote |
 | [twitter](../neurons/twitter/)                     | Send a Twit from kalliope                                                               | twitter           |
+| [wake_on_lan](../neurons/wake_on_lan/)             | Wake on lan a computer                                                                  | Wake on lan       |
 | [wikipedia](../neurons/wikipedia/)                 | Search for a page on Wikipedia                                                          | wikipedia         |
 

+ 78 - 9
core/ConfigurationManager/BrainLoader.py

@@ -15,12 +15,27 @@ logger = logging.getLogger("kalliope")
 
 
 class BrainLoader(object):
+    """
+    This Class is used to get the brain YAML and the Brain as an object
+    """
 
     def __init__(self):
         pass
 
     @classmethod
     def get_yaml_config(cls, file_path=None):
+        """
+        Class Methods which loads default or the provided YAML file and return it as a String
+        :param file_path: the brain file path to load
+        :type file_path: String
+        :return: The loaded brain YAML
+        :rtype: String
+
+        :Example:
+            brain_yaml = BrainLoader.get_yaml_config(/var/tmp/brain.yml)
+
+        .. warnings:: Class Method
+        """
         if file_path is None:
             brain_file_path = cls._get_root_brain_path()
         else:
@@ -30,9 +45,19 @@ class BrainLoader(object):
     @classmethod
     def get_brain(cls, file_path=None):
         """
-        return a brain object from YAML settings
-        :return: Brain object
+        Class Methods which loads default or the provided YAML file and return a Brain
+
+        :param file_path: the brain file path to load
+        :type file_path: String
+        :return: The loaded Brain
         :rtype: Brain
+
+        :Example:
+
+            brain = BrainLoader.get_brain(file_path="/var/tmp/brain.yml")
+
+        .. seealso:: Brain
+        .. warnings:: Class Method
         """
 
         # Instantiate a brain
@@ -46,7 +71,7 @@ class BrainLoader(object):
             # create list of Synapse
             synapses = list()
             for synapses_dict in dict_brain:
-                if "includes" not in synapses_dict: # we don't need to check includes as it's not a synapse
+                if "includes" not in synapses_dict:     # we don't need to check includes as it's not a synapse
                     if ConfigurationChecker().check_synape_dict(synapses_dict):
                         # print "synapses_dict ok"
                         name = synapses_dict["name"]
@@ -71,9 +96,20 @@ class BrainLoader(object):
     def _get_neurons(neurons_dict):
         """
         Get a list of Neuron object from a neuron dict
-        :param neurons_dict:
-        :return:
+
+        :param neurons_dict: Neuron name or dictionary of Neuron_name/Neuron_parameters
+        :type neurons_dict: String or dict
+        :return: A list of Neurons
+        :rtype: List
+
+        :Example:
+
+            neurons = cls._get_neurons(synapses_dict["neurons"])
+
+        .. seealso:: Neuron
+        .. warnings:: Static and Private
         """
+
         neurons = list()
         for neuron_dict in neurons_dict:
             if isinstance(neuron_dict, dict):
@@ -96,6 +132,21 @@ class BrainLoader(object):
 
     @classmethod
     def _get_signals(cls, signals_dict):
+        """
+        Get a list of Signal object from a signals dict
+
+        :param signals_dict: Signal name or dictionary of Signal_name/Signal_parameters
+        :type signals_dict: String or dict
+        :return: A list of Event and/or Order
+        :rtype: List
+
+        :Example:
+
+            signals = cls._get_signals(synapses_dict["signals"])
+
+        .. seealso:: Event, Order
+        .. warnings:: Class method and Private
+        """
         # print signals_dict
         signals = list()
         for signal_dict in signals_dict:
@@ -108,7 +159,21 @@ class BrainLoader(object):
 
     @staticmethod
     def _get_event_or_order_from_dict(signal_or_event_dict):
+        """
+        The signal is either an Event or an Order
 
+        :param signal_or_event_dict: A dict of event or signal
+        :type signal_or_event_dict: dict
+        :return: The object corresponding to An Order or an Event
+        :rtype: An Order or an Event
+
+        :Example:
+
+            event_or_order = cls._get_event_or_order_from_dict(signal_dict)
+
+        .. seealso:: Event, Order
+        .. warnings:: Static method and Private
+        """
         if 'event' in signal_or_event_dict:
             # print "is event"
             event = signal_or_event_dict["event"]
@@ -124,8 +189,15 @@ class BrainLoader(object):
     def _get_root_brain_path():
         """
         Return the full path of the default brain file
-        :return:
+
+        :Example:
+
+            brain.brain_file = cls._get_root_brain_path()
+
+        .. raises:: IOError
+        .. warnings:: Static method and Private
         """
+
         # get current script directory path. We are in /an/unknown/path/kalliope/core/ConfigurationManager
         cur_script_directory = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
         # get parent dir. Now we are in /an/unknown/path/kalliope
@@ -135,6 +207,3 @@ class BrainLoader(object):
         if os.path.isfile(brain_path):
             return brain_path
         raise IOError("Default brain.yml file not found")
-
-
-

+ 138 - 17
core/ConfigurationManager/ConfigurationChecker.py

@@ -4,48 +4,90 @@ from core.Utils import ModuleNotFoundError
 
 
 class InvalidSynapeName(Exception):
+    """
+    The name of the synapse is not correct. It should only contains alphanumerics at the beginning and the end of
+    its name. It can also contains dash in beetween alphanumerics.
+    """
     pass
 
 
 class NoSynapeName(Exception):
+    """
+    A synapse needs a name
+    """
     pass
 
 
 class NoSynapeNeurons(Exception):
+    """
+    A synapse must contains at least one neuron
+
+    .. seealso:: Synapse, Neuron
+    """
     pass
 
 
 class NoSynapeSignals(Exception):
+    """
+    A synapse must contains at least an Event or an Order
+
+    .. seealso:: Event, Order
+    """
     pass
 
 
 class NoValidSignal(Exception):
-    pass
+    """
+    A synapse must contains at least a valid Event or an Order
 
+    .. seealso:: Event, Order
+    """
 
-class NoEventID(Exception):
     pass
 
 
 class NoEventPeriod(Exception):
-    pass
-
+    """
+    An Event must contains a period corresponding to its execution
 
-class MultipleSameSynapseName(Exception):
+    .. seealso:: Event
+    """
     pass
 
 
-class NotValidSynapseName(Exception):
+class MultipleSameSynapseName(Exception):
+    """
+    A synapse name must be unique
+    """
     pass
 
 
 class ConfigurationChecker:
+    """
+    This Class provides all method to Check the configuration files are properly set up.
+    """
 
     def __init__(self):
         pass
 
     @staticmethod
     def check_synape_dict(synape_dict):
+        """
+        Return True if the provided dict is well corresponding to a Synapse
+
+        :param synape_dict: The synapse Dictionary
+        :type synape_dict: Dict
+        :return: True if synapse are ok
+        :rtype: Boolean
+
+        :Example:
+
+            ConfigurationChecker().check_synape_dict(synapses_dict):
+
+        .. seealso:: Synapse
+        .. raises:: NoSynapeName, InvalidSynapeName, NoSynapeNeurons, NoSynapeSignals
+        .. warnings:: Static and Public
+        """
 
         if 'name' not in synape_dict:
             raise NoSynapeName("The Synapse does not have a name: %s" % synape_dict)
@@ -71,17 +113,35 @@ class ConfigurationChecker:
     def check_neuron_dict(neuron_dict):
         """
         Check received neuron dict is valid:
-        - neuron exist
-        :param neuron_dict:
-        :return:
+
+        :param neuron_dict: The neuron Dictionary
+        :type neuron_dict: Dict
+        :return: True if neuron is ok
+        :rtype: Boolean
+
+        :Example:
+
+            ConfigurationChecker().check_neuron_dict(neurons_dict):
+
+        .. seealso:: Synapse
+        .. raises:: ModuleNotFoundError
+        .. warnings:: Static and Public
         """
-        def check_neuron_exist(neuron_name):
+
+        def check_neuron_exist(neuron_module_name):
+            """
+            Return True if the neuron_name python Class exist in neurons package
+            :param neuron_module_name: Name of the neuron module to check
+            :type neuron_module_name: str
+            :return:
+            """
             package_name = "neurons"
-            mod = __import__(package_name, fromlist=[neuron_name])
+            mod = __import__(package_name, fromlist=[neuron_module_name])
             try:
-                getattr(mod, neuron_name)
+                getattr(mod, neuron_module_name)
             except AttributeError:
-                raise ModuleNotFoundError("The module %s does not exist in package %s" % (neuron_name, package_name))
+                raise ModuleNotFoundError("The module %s does not exist in package %s" % (neuron_module_name,
+                                                                                          package_name))
             return True
 
         if isinstance(neuron_dict, dict):
@@ -93,12 +153,46 @@ class ConfigurationChecker:
 
     @staticmethod
     def check_signal_dict(signal_dict):
+        """
+        Check received signal dictionary is valid:
+
+        :param signal_dict: The signal Dictionary
+        :type signal_dict: Dict
+        :return: True if signal are ok
+        :rtype: Boolean
+
+        :Example:
+
+            ConfigurationChecker().check_signal_dict(signal_dict):
+
+        .. seealso:: Order, Event
+        .. raises:: NoValidSignal
+        .. warnings:: Static and Public
+        """
+
         if ('event' not in signal_dict) and ('order' not in signal_dict):
             raise NoValidSignal("The signal is not an event or an order %s" % signal_dict)
         return True
 
     @staticmethod
     def check_event_dict(event_dict):
+        """
+        Check received event dictionary is valid:
+
+        :param event_dict: The event Dictionary
+        :type event_dict: Dict
+        :return: True if event are ok
+        :rtype: Boolean
+
+        :Example:
+
+            ConfigurationChecker().check_event_dict(event_dict):
+
+        .. seealso::  Event
+        .. raises:: NoEventPeriod
+        .. warnings:: Static and Public
+        """
+
         if event_dict is None:
             raise NoEventPeriod("Event must contain a period: %s" % event_dict)
 
@@ -106,6 +200,22 @@ class ConfigurationChecker:
 
     @staticmethod
     def check_order_dict(order_dict):
+        """
+        Check received order dictionary is valid:
+
+        :param order_dict: The Order Dict
+        :type order_dict: Dict
+        :return: True if event are ok
+        :rtype: Boolean
+
+        :Example:
+
+            ConfigurationChecker().check_order_dict(order_dict):
+
+        .. seealso::  Order
+        .. warnings:: Static and Public
+        """
+
         if order_dict is not None:
             return True
         return False
@@ -114,11 +224,22 @@ class ConfigurationChecker:
     def check_synapes(synapses_list):
         """
         Check the synapse list is ok:
-         - No double same name
-        :param synapses_list:
-        :type synapses_list: list of Synapse
-        :return:
+                - No double same name
+
+        :param synapses_list: The Synapse List
+        :type synapses_list: List
+        :return: list of Synapse
+        :rtype: List
+
+        :Example:
+
+            ConfigurationChecker().check_synapes(order_dict):
+
+        .. seealso::  Synapse
+        .. raises:: MultipleSameSynapseName
+        .. warnings:: Static and Public
         """
+
         seen = set()
         for synapse in synapses_list:
             # convert ascii to UTF-8

+ 213 - 26
core/ConfigurationManager/SettingLoader.py

@@ -2,7 +2,6 @@ import logging
 
 from YAMLLoader import YAMLLoader
 from core.FileManager import FileManager
-from core.Models import Singleton
 from core.Models.RestAPI import RestAPI
 from core.Models.Settings import Settings
 from core.Models.Stt import Stt
@@ -16,24 +15,56 @@ logger = logging.getLogger("kalliope")
 
 
 class SettingInvalidException(Exception):
+    """
+    Some data must match the expected value/type
+
+    .. seealso:: Settings
+    """
     pass
 
 
 class NullSettingException(Exception):
+    """
+    Some Attributes can not be Null
+
+    .. seealso:: Settings
+    """
     pass
 
 
 class SettingNotFound(Exception):
+    """
+    Some Attributes are missing
+
+    .. seealso:: Settings
+    """
     pass
 
 
 class SettingLoader(object):
+    """
+    This Class is used to get the Settings YAML and the Settings as an object
+    """
 
     def __init__(self):
         pass
 
     @classmethod
     def get_yaml_config(cls, file_path=None):
+        """
+        Class Methods which loads default or the provided YAML file and return it as a String
+
+        :param file_path: the setting file path to load if None takes default
+        :type file_path: str
+        :return: The loaded settings YAML
+        :rtype: dict
+
+        :Example:
+            settings_yaml = SettingLoader.get_yaml_config(/var/tmp/settings.yml)
+
+        .. warnings:: Class Method
+        """
+
         if file_path is None:
             file_path = FILE_NAME
         return YAMLLoader.get_config(file_path)
@@ -41,8 +72,19 @@ class SettingLoader(object):
     @classmethod
     def get_settings(cls, file_path=None):
         """
-        Return a Settings object from settings.yml file
-        :return:
+        Class Methods which loads default or the provided YAML file and return a Settings Object
+
+        :param file_path: the setting file path to load
+        :type file_path: str
+        :return: The loaded Settings
+        :rtype: Settings
+
+        :Example:
+
+            settings = SettingLoader.get_settings(file_path="/var/tmp/settings.yml")
+
+        .. seealso:: Settings
+        .. warnings:: Class Method
         """
 
         # create a new setting
@@ -64,16 +106,16 @@ class SettingLoader(object):
             cache_path = cls._get_cache_path(settings)
 
             # Load the setting singleton with the parameters
-            setting_object.default_tts_name=default_tts_name
-            setting_object.default_stt_name=default_stt_name
-            setting_object.default_trigger_name=default_trigger_name
-            setting_object.stts=stts
-            setting_object.ttss=ttss
-            setting_object.triggers=triggers
-            setting_object.random_wake_up_answers=random_wake_up_answers
-            setting_object.random_wake_up_sounds=random_wake_up_sounds
-            setting_object.rest_api=rest_api
-            setting_object.cache_path=cache_path
+            setting_object.default_tts_name = default_tts_name
+            setting_object.default_stt_name = default_stt_name
+            setting_object.default_trigger_name = default_trigger_name
+            setting_object.stts = stts
+            setting_object.ttss = ttss
+            setting_object.triggers = triggers
+            setting_object.random_wake_up_answers = random_wake_up_answers
+            setting_object.random_wake_up_sounds = random_wake_up_sounds
+            setting_object.rest_api = rest_api
+            setting_object.cache_path = cache_path
             # The Settings Singleton is loaded
             setting_object.is_loaded = True
 
@@ -81,6 +123,22 @@ class SettingLoader(object):
 
     @staticmethod
     def _get_default_speech_to_text(settings):
+        """
+        Get the default speech to text defined in the settings.yml file
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: the default speech to text
+        :rtype: str
+
+        :Example:
+
+            default_stt_name = cls._get_default_speech_to_text(settings)
+
+        .. seealso:: Stt
+        .. raises:: NullSettingException, SettingNotFound
+        .. warnings:: Static and Private
+        """
 
         try:
             default_speech_to_text = settings["default_speech_to_text"]
@@ -93,6 +151,23 @@ class SettingLoader(object):
 
     @staticmethod
     def _get_default_text_to_speech(settings):
+        """
+        Get the default text to speech defined in the settings.yml file
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: the default text to speech
+        :rtype: str
+
+        :Example:
+
+            default_tts_name = cls._get_default_text_to_speech(settings)
+
+        .. seealso:: Tts
+        .. raises:: NullSettingException, SettingNotFound
+        .. warnings:: Static and Private
+        """
+
         try:
             default_text_to_speech = settings["default_text_to_speech"]
             if default_text_to_speech is None:
@@ -104,6 +179,22 @@ class SettingLoader(object):
 
     @staticmethod
     def _get_default_trigger(settings):
+        """
+        Get the default trigger defined in the settings.yml file
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: the default trigger
+        :rtype: str
+
+        :Example:
+
+            default_trigger_name = cls._get_default_trigger(settings)
+
+        .. seealso:: Trigger
+        .. raises:: NullSettingException, SettingNotFound
+        .. warnings:: Static and Private
+        """
+
         try:
             default_trigger = settings["default_trigger"]
             if default_trigger is None:
@@ -117,13 +208,25 @@ class SettingLoader(object):
     def _get_stts(cls, settings):
         """
         Return a list of stt object
-        :param settings: loaded settings file
+
+        :param settings: The YAML settings file
+        :type settings: dict
         :return: List of Stt
+        :rtype: list
+
+        :Example:
+
+            stts = cls._get_stts(settings)
+
+        .. seealso:: Stt
+        .. raises:: SettingNotFound
+        .. warnings:: Class Method and Private
         """
+
         try:
             speechs_to_text_list = settings["speech_to_text"]
         except KeyError:
-            raise NullSettingException("speech_to_text settings not found")
+            raise SettingNotFound("speech_to_text settings not found")
 
         stts = list()
         for speechs_to_text_el in speechs_to_text_list:
@@ -143,10 +246,23 @@ class SettingLoader(object):
     @classmethod
     def _get_ttss(cls, settings):
         """
-        Return a list of Tts object
-        :param settings: loaded settings file
-        :return: List of Tts
+
+        Return a list of stt object
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: List of Ttss
+        :rtype: list
+
+        :Example:
+
+            ttss = cls._get_ttss(settings)
+
+        .. seealso:: Tts
+        .. raises:: SettingNotFound
+        .. warnings:: Class Method and Private
         """
+
         try:
             text_to_speech_list = settings["text_to_speech"]
         except KeyError, e:
@@ -171,9 +287,21 @@ class SettingLoader(object):
     def _get_triggers(cls, settings):
         """
         Return a list of Trigger object
-        :param settings: loaded settings file
+
+        :param settings: The YAML settings file
+        :type settings: dict
         :return: List of Trigger
+        :rtype: list
+
+        :Example:
+
+            triggers = cls._get_triggers(settings)
+
+        .. seealso:: Trigger
+        .. raises:: SettingNotFound
+        .. warnings:: Class Method and Private
         """
+
         try:
             triggers_list = settings["triggers"]
         except KeyError, e:
@@ -197,10 +325,22 @@ class SettingLoader(object):
     @classmethod
     def _get_random_wake_up_answers(cls, settings):
         """
-        return a list of string
-        :param settings:
-        :return:
+        Return a list of the wake up answers set up on the settings.yml file
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: List of wake up answers
+        :rtype: list of str
+
+        :Example:
+
+            wakeup = cls._get_random_wake_up_answers(settings)
+
+        .. seealso::
+        .. raises:: NullSettingException
+        .. warnings:: Class Method and Private
         """
+
         try:
             random_wake_up_answers_list = settings["random_wake_up_answers"]
         except KeyError:
@@ -216,10 +356,22 @@ class SettingLoader(object):
     @classmethod
     def _get_random_wake_up_sounds(cls, settings):
         """
-        return a list of string
-        :param settings:
-        :return: List of string
+        Return a list of the wake up sounds set up on the settings.yml file
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: list of wake up sounds
+        :rtype: list of str
+
+        :Example:
+
+            wakeup_sounds = cls._get_random_wake_up_sounds(settings)
+
+        .. seealso::
+        .. raises:: NullSettingException
+        .. warnings:: Class Method and Private
         """
+
         try:
             random_wake_up_sounds_list = settings["random_wake_up_sounds"]
         except KeyError:
@@ -234,6 +386,23 @@ class SettingLoader(object):
 
     @classmethod
     def _get_rest_api(cls, settings):
+        """
+        Return the settings of the RestApi
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: the RestApi object
+        :rtype: RestApi
+
+        :Example:
+
+            rest_api = cls._get_rest_api(settings)
+
+        .. seealso:: RestApi
+        .. raises:: SettingNotFound, NullSettingException, SettingInvalidException
+        .. warnings:: Class Method and Private
+        """
+
         try:
             rest_api = settings["rest_api"]
         except KeyError, e:
@@ -271,13 +440,31 @@ class SettingLoader(object):
                 raise SettingNotFound("%s settings not found" % e)
 
             # config ok, we can return the rest api object
-            rest_api_obj = RestAPI(password_protected=password_protected, login=login, password=password, active=active, port=port)
+            rest_api_obj = RestAPI(password_protected=password_protected, login=login, password=password,
+                                   active=active, port=port)
             return rest_api_obj
         else:
             raise NullSettingException("rest_api settings cannot be null")
 
     @classmethod
     def _get_cache_path(cls, settings):
+        """
+        Return the path where to store the cache
+
+        :param settings: The YAML settings file
+        :type settings: dict
+        :return: the path to store the cache
+        :rtype: String
+
+        :Example:
+
+            cache_path = cls._get_cache_path(settings)
+
+        .. seealso::
+        .. raises:: SettingNotFound, NullSettingException, SettingInvalidException
+        .. warnings:: Class Method and Private
+        """
+
         try:
             cache_path = settings["cache_path"]
         except KeyError, e:

+ 32 - 5
core/ConfigurationManager/YAMLLoader.py

@@ -8,10 +8,16 @@ logger = logging.getLogger("kalliope")
 
 
 class YAMLFileNotFound(Exception):
+    """
+    YAML file has not been found
+    """
     pass
 
 
 class YAMLLoader:
+    """
+    Simple Class to Verify / Load a YAML file.
+    """
 
     def __init__(self):
         pass
@@ -19,9 +25,22 @@ class YAMLLoader:
     @classmethod
     def get_config(cls, yaml_file):
         """
-        Load settings file
-        :return: cfg : the configuration file
+        Return the provided YAML configuration file
+
+        :param yaml_file: The path of the configuration file
+        :type yaml_file: String
+        :return: the configuration file
+        :rtype: String
+
+        :Example:
+
+            YAMLLoader.get_config(brain_file_path)
+
+        .. seealso::  SettingLoader, BrainLoader
+        .. raises:: YAMLFileNotFound
+        .. warnings:: Class Method and Public
         """
+
         current_dir = os.path.dirname(os.path.abspath(__file__))
         logger.debug("Current dir: %s " % current_dir)
         root_dir = os.path.join(current_dir, "../../")
@@ -38,6 +57,9 @@ class YAMLLoader:
 
 
 class IncludeImport(object):
+    """
+    This class manages the Include Import statement in the brain.yml file
+    """
 
     def __init__(self, file_path):
         """
@@ -63,14 +85,19 @@ class IncludeImport(object):
                         self.update(yaml.load(open(inc)))
 
     def get_data(self):
+        """
+        :return: the data for the IncludeImport
+        """
         return self.data
 
     def update(self, data_to_add):
-        # print "cur_data: %s" % self.data
-        # print "data to add %s" % data_to_add
+        """
+        Method to Add an other Include statement to the original brain.yml file
+        :param data_to_add: the data to add to the current brain.yml, provided by an Include Statement
+        """
+
         # we add each synapse inside the extended brain into the main brain data
         if data_to_add is not None:
             for el in data_to_add:
                 self.data.append(el)
-        # print "final data: %s" % self.data
 

+ 27 - 7
core/CrontabManager.py

@@ -1,16 +1,20 @@
-from crontab import CronTab
+import logging
+
 from crontab import CronSlices
+from crontab import CronTab
 
 from core import Utils
-from core.ConfigurationManager.BrainLoader import BrainLoader
 from core.Models import Event
-import logging
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
 
 
 class InvalidCrontabPeriod(Exception):
+    """
+    Event are based on the Crontab. The Period must be corresponding to the Crontab format
+    .. seealso:: Event
+    """
     pass
 
 CRONTAB_COMMENT = "KALLIOPE"
@@ -28,7 +32,6 @@ class CrontabManager:
         """
         Remove all line in crontab with the CRONTAB_COMMENT
         Then add back line from event in the brain.yml
-        :return:
         """
         # clean the current crontab from all Kalliope event
         self._remove_all_job()
@@ -42,6 +45,19 @@ class CrontabManager:
                     self._add_event(period_string=signal.period, event_id=synapse.name)
 
     def _add_event(self, period_string, event_id):
+        """
+        Add a single event in the crontab.
+        Will add a line like:
+        <period_string> python /path/to/kalliope.py start --brain-file /path/to/brain.yml --run-synapse "<event_id>"
+
+        E.g:
+        30 7 * * * python /home/me/kalliope/kalliope.py start --brain-file /home/me/brain.yml --run-synapse  "Say-hello"
+        :param period_string: crontab period
+        :type period_string: str
+        :param event_id:
+        :type event_id: str
+        :return:
+        """
         my_user_cron = CronTab(user=True)
         job = my_user_cron.new(command=self.base_command+" "+str("\"" + event_id + "\""), comment=CRONTAB_COMMENT)
         if CronSlices.is_valid(period_string):
@@ -54,15 +70,18 @@ class CrontabManager:
         Utils.print_info("Synapse \"%s\" added to the crontab" % event_id)
 
     def get_jobs(self):
+        """
+        Return all current jobs in the crontab
+        :return:
+        """
         return self.my_user_cron.find_comment(CRONTAB_COMMENT)
 
     def _remove_all_job(self):
         """
         Remove all line in crontab that are attached to Kalliope
-        :return:
         """
-        iter = self.my_user_cron.find_comment(CRONTAB_COMMENT)
-        for job in iter:
+        iter_item = self.my_user_cron.find_comment(CRONTAB_COMMENT)
+        for job in iter_item:
             logger.debug("remove job %s from crontab" % job)
             self.my_user_cron.remove(job)
         # write the file
@@ -80,6 +99,7 @@ class CrontabManager:
         Return the path of the entry point of Kalliope
         Example: /home/user/kalliope/kalliope.py
         :return: The path of the entry point script kalliope.py
+        :rtype: str
         """
         import inspect
         import os

+ 29 - 6
core/FileManager.py

@@ -1,6 +1,5 @@
 import logging
 import os
-import shutil
 
 
 logging.basicConfig()
@@ -8,16 +7,33 @@ logger = logging.getLogger("kalliope")
 
 
 class FileManager:
+    """
+    Class used to manage Files
+    """
     def __init__(self):
         pass
 
     @staticmethod
     def create_directory(cache_path):
+        """
+        Create a directory at the provided `cache_path`
+        :param cache_path: the path of the directory to create
+        :type cache_path: str
+        """
         if not os.path.exists(cache_path):
             os.makedirs(cache_path)
 
     @staticmethod
     def write_in_file(file_path, content):
+        """
+        Write contents into a file
+        :param file_path: the path of the file to write on
+        :type file_path: str
+        :param content: the contents to write in the file
+        :type content: str
+
+        .. raises:: IOError
+        """
         try:
             with open(file_path, "wb") as file_open:
                 file_open.write(content)
@@ -26,20 +42,25 @@ class FileManager:
         except IOError as e:
             logger.error("I/O error(%s): %s", e.errno, e.strerror)
 
-    @staticmethod
-    def wipe_cache(cache_path):
-        shutil.rmtree(cache_path)
-
     @staticmethod
     def file_is_empty(file_path):
+        """
+        Check if the file is empty
+        :param file_path: the path of the file
+        :return: True if the file is empty, False otherwise
+        """
         return os.path.getsize(file_path) == 0
 
     @staticmethod
     def remove_file(file_path):
+        """
+        Remove the file locate at the provided `file_path`
+        :param file_path:
+        :return: True if the file has been removed successfully, False otherwise
+        """
         if os.path.exists(file_path):
             return os.remove(file_path)
 
-
     @staticmethod
     def is_path_creatable(pathname):
         """
@@ -56,6 +77,8 @@ class FileManager:
         either currently exists or is hypothetically creatable; `False` otherwise.
 
         This function is guaranteed to _never_ raise exceptions.
+
+        .. raises:: OSError
         """
         try:
             return os.path.exists(pathname) or FileManager.is_path_creatable(pathname)

+ 14 - 11
core/MainController.py

@@ -2,15 +2,15 @@ import logging
 import os
 import random
 
+from flask import Flask
+
 from core import Utils
 from core.ConfigurationManager import SettingLoader
-from core.ConfigurationManager.BrainLoader import BrainLoader
 from core.OrderAnalyser import OrderAnalyser
 from core.OrderListener import OrderListener
 from core.Players import Mplayer
-from core.TriggerLauncher import TriggerLauncher
-from flask import Flask
 from core.RestAPI.FlaskAPI import FlaskAPI
+from core.TriggerLauncher import TriggerLauncher
 from neurons import Say
 
 logging.basicConfig()
@@ -18,6 +18,9 @@ logger = logging.getLogger("kalliope")
 
 
 class MainController:
+    """
+    This Class is the global controller of the application.
+    """
     def __init__(self, brain=None):
         self.brain = brain
         # get global configuration
@@ -39,11 +42,10 @@ class MainController:
 
     def callback(self):
         """
-        # we have detected the hotword, we can now pause the kalliope Trigger for a while
-        # The user can speak out loud his order during this time.
-        :return:
+        we have detected the hotword, we can now pause the Trigger for a while
+        The user can speak out loud his order during this time.
         """
-        # pause the snowboy process
+        # pause the trigger process
         self.trigger_instance.pause()
         # start listening for an order
         self.order_listener.start()
@@ -57,7 +59,8 @@ class MainController:
     def analyse_order(self, order):
         """
         Receive an order, try to retreive it in the brain.yml to launch to attached plugins
-        :return:
+        :param order: the sentence received
+        :type order: str
         """
         order_analyser = OrderAnalyser(order, main_controller=self, brain=self.brain)
         order_analyser.start()
@@ -72,7 +75,7 @@ class MainController:
     def _get_default_trigger(self):
         """
         Return an instance of the default trigger
-        :return:
+        :return: Trigger
         """
         for trigger in self.settings.triggers:
             if trigger.name == self.settings.default_trigger_name:
@@ -84,8 +87,8 @@ class MainController:
         Return a path of a sound to play
         If the path is absolute, test if file exist
         If the path is relative, we check if the file exist in the sound folder
-        :param random_wake_up_sounds:
-        :return:
+        :param random_wake_up_sounds: List of wake_up sounds
+        :return: path of a sound to play
         """
         # take first randomly a path
         random_path = random.choice(random_wake_up_sounds)

+ 5 - 0
core/Models/Brain.py

@@ -3,6 +3,11 @@ from core.Models import Singleton
 
 @Singleton
 class Brain:
+    # TODO review the Singleton, should be Instantiate at the BrainLoader level
+    """
+    This Class is a Singleton Representing the Brain.yml file with synapse
+    .. note:: the is_loaded Boolean is True when the Brain has been properly loaded.
+    """
 
     def __init__(self, synapses=None, brain_file=None, brain_yaml=None):
         self.synapses = synapses

+ 13 - 0
core/Models/Event.py

@@ -1,4 +1,10 @@
 class Event(object):
+    """
+    This Class is representing an Event which is raised by when the System at some defined time.
+
+    .. note:: Events are based on the system crontab
+    """
+
     def __init__(self, period):
         self.period = period
 
@@ -7,6 +13,13 @@ class Event(object):
                                    self.period)
 
     def serialize(self):
+        """
+        This method allows to serialize in a proper way this object
+
+        :return: A dict of name / period
+        :rtype: Dict
+        """
+
         return {
             'event': self.period
         }

+ 11 - 1
core/Models/Neuron.py

@@ -1,11 +1,21 @@
+class Neuron(object):
+    """
+    This Class is representing a Neuron which is corresponding to an action to perform.
 
+    .. note:: Neurons are defined in the brain file
+    """
 
-class Neuron(object):
     def __init__(self, name=None, parameters=None):
         self.name = name
         self.parameters = parameters
 
     def serialize(self):
+        """
+        This method allows to serialize in a proper way this object
+
+        :return: A dict of name and parameters
+        :rtype: Dict
+        """
         return {
             'name': self.name,
             'parameters': str(self.parameters)

+ 13 - 0
core/Models/Order.py

@@ -1,4 +1,10 @@
 class Order(object):
+    """
+    This Class is representing an Order which is raised by when an entry (Vocal/REST/ anything ...) is matching it.
+
+    .. note:: Order are defined in the brain file for each synapse.
+    """
+
     def __init__(self, sentence):
         self.sentence = sentence
 
@@ -6,6 +12,13 @@ class Order(object):
         return "%s: Sentence: %s" % (self.__class__.__name__, self.sentence)
 
     def serialize(self):
+        """
+        This method allows to serialize in a proper way this object
+
+        :return: A dict of order
+        :rtype: Dict
+        """
+
         return {
             'order': self.sentence
         }

+ 4 - 0
core/Models/RestAPI.py

@@ -1,4 +1,8 @@
 class RestAPI(object):
+    """
+    This Class is representing the rest API with all its configuration.
+    """
+
     def __init__(self, password_protected=None, login=None, password=None, active=None, port=None):
         """
 

+ 6 - 0
core/Models/Settings.py

@@ -3,6 +3,12 @@ from core.Models import Singleton
 
 @Singleton
 class Settings(object):
+    # TODO review the Singleton, should be Instantiate at the BrainLoader level
+    """
+    This Class is a Singleton Representing the settings.yml file with synapse
+
+    .. note:: the is_loaded Boolean is True when the Settings has been properly loaded.
+    """
     def __init__(self,
                  default_tts_name=None,
                  default_stt_name=None,

+ 2 - 0
core/Models/Singleton.py

@@ -1,5 +1,7 @@
 class Singleton:
     """
+    (From Stackoverflow : http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python)
+
     A non-thread-safe helper class to ease implementing singletons.
     This should be used as a decorator -- not a metaclass -- to the
     class that should be a singleton.

+ 5 - 1
core/Models/Stt.py

@@ -1,6 +1,10 @@
+class Stt(object):
+    """
+    This Class is representing a Speech To Text (STT) element with name and parameters
 
+    .. note:: must be defined in the settings.yml
+    """
 
-class Stt(object):
     def __init__(self, name=None, parameters=None):
         self.name = name
         self.parameters = parameters

+ 14 - 1
core/Models/Synapse.py

@@ -1,10 +1,23 @@
 class Synapse(object):
-    def __init__(self, name, neurons, signals):
+    """
+    This Class is representing a Synapse with its name, and a dict of Neurons and a dict of signals
+
+    .. note:: must be defined in the brain.yml
+    """
+
+    def __init__(self, name=None, neurons=None, signals=None):
         self.name = name
         self.neurons = neurons
         self.signals = signals
 
     def serialize(self):
+        """
+        This method allows to serialize in a proper way this object
+
+        :return: A dict of name, neurons, signals
+        :rtype: Dict
+        """
+
         return {
             'name': self.name,
             'neurons': [e.serialize() for e in self.neurons],

+ 5 - 2
core/Models/Trigger.py

@@ -1,10 +1,13 @@
+class Trigger(object):
+    """
+    This Class is representing a Trigger with its name and parameters
 
+    .. note:: must be defined in the settings.yml
+    """
 
-class Trigger(object):
     def __init__(self, name=None, parameters=None):
         self.name = name
         self.parameters = parameters
 
     def __str__(self):
         return "Trigger name: %s, parameters: %s" % (str(self.name), str(self.parameters))
-

+ 5 - 1
core/Models/Tts.py

@@ -1,6 +1,10 @@
+class Tts(object):
+    """
+    This Class is representing a Text To Speech (TTS) with its name and parameters
 
+    .. note:: must be defined in the settings.yml
+    """
 
-class Tts(object):
     def __init__(self, name=None, parameters=None):
         self.name = name
         self.parameters = parameters

+ 40 - 16
core/NeuronModule.py

@@ -16,34 +16,45 @@ logger = logging.getLogger("kalliope")
 
 
 class InvalidParameterException(Exception):
+    """
+   Some Neuron parameters are invalid.
+    """
     pass
 
 
 class MissingParameterException(Exception):
+    """
+    Some Neuron parameters are missing.
+    """
     pass
 
 
 class NoTemplateException(Exception):
-    pass
-
-
-class MultipleTemplateException(Exception):
+    """
+    You must specify a say_template or a file_template
+    """
     pass
 
 
 class TemplateFileNotFoundException(Exception):
+    """
+    Template file can not be found. Check the provided path.
+    """
     pass
 
 
 class TTSModuleNotFound(Exception):
-    pass
-
-
-class TTSNotInstantiable(Exception):
+    """
+    TTS module can not be find. It must be configured in the settings file.
+    """
     pass
 
 
 class NeuronModule(object):
+    """
+    This Abstract Class is representing main Class for Neuron.
+    Each Neuron must implement this Class.
+    """
     def __init__(self, **kwargs):
         """
         Class used by neuron for talking
@@ -81,8 +92,9 @@ class NeuronModule(object):
         If it's a string, simply use the TTS with the message
         If it's a list, we select randomly a string in the list and give it to the TTS
         If it's a dict, we use the template given in parameter to create a string that we give to the TTS
-        :param message: Can be a String or a dict
-        :return:
+        :param message: Can be a String or a dict or a list
+
+        .. raises:: TTSModuleNotFound
         """
         logger.debug("NeuronModule Say() called with message: %s" % message)
 
@@ -109,7 +121,7 @@ class NeuronModule(object):
                 raise TTSModuleNotFound("The tts module name %s does not exist in settings file" % self.tts)
             # change the cache settings with the one precised for the current neuron
             if self.override_cache is not None:
-                tts_object.parameter = self._update_cache_var(self.override_cache, tts_object.parameter)
+                tts_object.parameters = self._update_cache_var(self.override_cache, tts_object.parameters)
 
             logger.debug("NeuroneModule: TTS args: %s" % tts_object)
 
@@ -121,9 +133,11 @@ class NeuronModule(object):
 
     def _get_message_from_dict(self, message_dict):
         """
-        Generate a message taht can be played by a TTS engine from a dict of variable and the jinja template
-        :param message_dict:
-        :return:
+        Generate a message that can be played by a TTS engine from a dict of variable and the jinja template
+        :param message_dict: the dict of message
+        :return: The message to say
+
+        .. raises:: TemplateFileNotFoundException
         """
         returned_message = None
 
@@ -162,11 +176,22 @@ class NeuronModule(object):
 
     @staticmethod
     def _get_content_of_file(real_file_template_path):
+        """
+        Return the content of a file in path <real_file_template_path>
+        :param real_file_template_path: path of the file to return the content
+        :return: file content str
+        """
         with open(real_file_template_path, 'r') as content_file:
             return content_file.read()
 
     @staticmethod
     def _update_cache_var(new_override_cache, args_list):
+        """
+        update the value for the key "cache" in the dict args_list
+        :param new_override_cache: cache bolean to set in place of the current one in args_list
+        :param args_list: arg list that contain "cache" to update
+        :return:
+        """
         logger.debug("args for TTS plugin before update: %s" % str(args_list))
         args_list["cache"] = new_override_cache
         logger.debug("args for TTS plugin after update: %s" % str(args_list))
@@ -176,8 +201,7 @@ class NeuronModule(object):
     def get_audio_from_stt(callback):
         """
         Call the default STT to get an audio sample and return it into the callback method
-        :param callback:
-        :return:
+        :param callback: A callback function
         """
         # call the order listener
         oa = OrderListener(callback=callback)

+ 1 - 6
core/NeuroneLauncher.py

@@ -6,10 +6,6 @@ logging.basicConfig()
 logger = logging.getLogger("kalliope")
 
 
-class NeuroneNotFoundError(Exception):
-    pass
-
-
 class NeuroneLauncher:
 
     def __init__(self):
@@ -20,9 +16,8 @@ class NeuroneLauncher:
         """
         Start a neuron plugin
         :param neuron: neuron object
-        :type neuron: Neurone
+        :type neuron: Neuron
         :return:
         """
         logger.debug("Run plugin \"%s\" with parameters %s" % (neuron.name, neuron.parameters))
         return Utils.get_dynamic_class_instantiation("neurons", neuron.name.capitalize(), neuron.parameters)
-

+ 12 - 0
core/OrderAnalyser.py

@@ -13,6 +13,9 @@ logger = logging.getLogger("kalliope")
 
 
 class OrderAnalyser:
+    """
+    This Class is used to compare the incoming message to the Signal/Order sentences.
+    """
     def __init__(self, order, main_controller=None, brain=None):
         """
         Class used to load brain and run neuron attached to the received order
@@ -28,6 +31,10 @@ class OrderAnalyser:
         logger.debug("OrderAnalyser, Received order: %s" % self.order)
 
     def start(self):
+        # TODO : refactor this method !!
+        """
+        This method matches the incoming messages to the signals/order sentences provided in the Brain
+        """
         synapses_found = False
         problem_in_neuron_found = False
         # create a dict of synapses that have benn launched
@@ -124,6 +131,11 @@ class OrderAnalyser:
 
     @staticmethod
     def _is_containing_bracket(sentence):
+        """
+        Return True if the text in <sentence> contains brackets
+        :param sentence:
+        :return:
+        """
         # print "sentence to test %s" % sentence
         pattern = r"{{|}}"
         # prog = re.compile(pattern)

+ 16 - 3
core/OrderListener.py

@@ -12,6 +12,12 @@ logger = logging.getLogger("kalliope")
 
 
 class OrderListener(Thread):
+    """
+    This Class allows to Listen to an Incoming voice order.
+
+    .. notes:: Thread are used to calibrate the sound of the microphone input with the noise while
+        starting to listen the incoming order. Basically it avoids delays.
+    """
 
     def __init__(self, callback=None, stt=None):
         """
@@ -19,8 +25,12 @@ class OrderListener(Thread):
         We now wait for an order spoken out loud by the user, translate the order into a text and run the action
          attached to this order from settings
         :param callback: callback function to call
+        :type callback: Callback function
         :param stt: Speech to text plugin name to load. If not provided,
+        :type stt: STT instance
         we will load the default one set in settings
+
+        .. seealso::  STT
         """
         # this is a trick to ignore ALSA output error
         # see http://stackoverflow.com/questions/7088672/pyaudio-working-but-spits-out-error-messages-each-time
@@ -32,6 +42,9 @@ class OrderListener(Thread):
         self.settings = SettingLoader.get_settings()
 
     def run(self):
+        """
+        Start thread
+        """
         self.load_stt_plugin()
 
     def load_stt_plugin(self):
@@ -47,7 +60,9 @@ class OrderListener(Thread):
 
     @staticmethod
     def _ignore_stderr():
-        """Try to forward PortAudio messages from stderr to /dev/null."""
+        """
+        Try to forward PortAudio messages from stderr to /dev/null.
+        """
         ffi = _FFI()
         ffi.cdef("""
         /* from stdio.h */
@@ -65,5 +80,3 @@ class OrderListener(Thread):
                 stdio.__stderrp = devnull
             except KeyError:
                 stdio.fclose(devnull)
-
-

+ 20 - 5
core/Players/Mplayer.py

@@ -5,17 +5,34 @@ import subprocess
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
 
-
 MPLAYER_EXEC_PATH = "/usr/bin/mplayer"
 
 
 class Mplayer(object):
+    """
+    This Class is representing the MPlayer Object used to play the all sound of the system.
+    """
 
     def __init__(self):
         pass
 
     @classmethod
     def play(cls, filepath):
+        """
+        Play the sound located in the provided filepath
+
+        :param filepath: The file path of the sound to play
+        :type filepath: str
+
+        :Example:
+
+            Mplayer.play(self.file_path)
+
+        .. seealso::  TTS
+        .. raises::
+        .. warnings:: Class Method and Public
+        """
+
         mplayer_exec_path = [MPLAYER_EXEC_PATH]
         mplayer_options = ['-slave', '-quiet']
         mplayer_command = list()
@@ -25,8 +42,6 @@ class Mplayer(object):
         mplayer_command.append(filepath)
         logger.debug("Mplayer cmd: %s" % str(mplayer_command))
 
-        FNULL = open(os.devnull, 'w')
-
-        subprocess.call(mplayer_command, stdout=FNULL, stderr=FNULL)
-
+        fnull = open(os.devnull, 'w')
 
+        subprocess.call(mplayer_command, stdout=fnull, stderr=fnull)

+ 9 - 10
core/ShellGui.py

@@ -22,7 +22,6 @@ def signal_handler(signal, frame):
     Used to catch a keyboard signal like Ctrl+C in order to kill the kalliope program
     :param signal: signal handler
     :param frame: execution frame
-    :return:
     """
     print "\n"
     Utils.print_info("Ctrl+C pressed. Killing Kalliope")
@@ -35,7 +34,10 @@ class ShellGui:
     def __init__(self, brain=None):
         """
         Load a GUI in a shell console for testing TTS, STT and brain configuration
-        :param brain:
+        :param brain: The Brain object provided by the brain.yml
+        :type brain: Brain
+
+        .. seealso:: Brain
         """
         # override brain
         self.brain = brain
@@ -54,7 +56,6 @@ class ShellGui:
         """
         Main menu of the shell UI.
         Provide a list of action the user can select to test his settings
-        :return:
         """
 
         code, tag = self.d.menu("Test your Kalliope settings from this menu",
@@ -74,7 +75,6 @@ class ShellGui:
         """
         Show the list of available STT.
         Clicking on a STT will load the engine to catch the user audio and return a text
-        :return:
         """
         # we get STT from settings
         stt_list = self.settings.stts
@@ -101,7 +101,7 @@ class ShellGui:
         - select a TTS engine to test
         - type a sentence
         - press ok and listen the generated audio from the typed text
-        :return:
+        :param sentence_to_test: the screen written sentence to test
         """
         continue_bool = True
         # if we don't have yet a sentence to test, we ask the user to type one
@@ -139,7 +139,6 @@ class ShellGui:
         Call the TTS
         :param tts_name: Name of the TTS module to launch
         :param sentence_to_test: String text to send to the TTS engine
-        :return:
         """
         sentence_to_test = sentence_to_test.encode('utf-8')
         tts_name = tts_name.encode('utf-8')
@@ -149,9 +148,10 @@ class ShellGui:
     @staticmethod
     def _get_choices_tuple_from_list(list_to_convert):
         """
-        Return a list of tup that can be used in Dialog menu
-        :param list_to_convert: List of object to convert into tuple
-        :return:
+            Return a list of tup that can be used in Dialog menu
+            :param list_to_convert: List of object to convert into tuple
+            :return: List of choices
+            :rtype: List
         """
         # create a list of tuple that can be used by the dialog menu
         choices = list()
@@ -175,7 +175,6 @@ class ShellGui:
     def show_synapses_test_menu(self):
         """
         Show a list of available synapse in the brain to run it directly
-        :return:
         """
 
         # create a tuple for the list menu

+ 5 - 1
core/SynapseLauncher.py

@@ -1,8 +1,12 @@
-from core.ConfigurationManager.BrainLoader import BrainLoader
 from core.NeuroneLauncher import NeuroneLauncher
 
 
 class SynapseNameNotFound(Exception):
+    """
+    The Synapse has not been found
+
+    .. seealso: Synapse
+    """
     pass
 
 

+ 3 - 0
core/TTS/TTSLauncher.py

@@ -17,6 +17,9 @@ class TTSLauncher(object):
         :param tts: TTS model
         :type tts: Tts
         :return: TTS module instance
+
+        .. seealso::  TTS
+        .. warnings:: Class Method and Public
         """
         logger.debug("get TTS module \"%s\" with parameters %s" % (tts.name, tts.parameters))
         return Utils.get_dynamic_class_instantiation("tts", tts.name.capitalize(), tts.parameters)

+ 21 - 8
core/TTS/TTSModule.py

@@ -12,25 +12,37 @@ logger = logging.getLogger("kalliope")
 
 
 class MissingTTSParameter(Exception):
+    """
+    Some TTS Parameters are missing in the settings.yml file.
+
+    .. seealose:: Settings
+    """
     pass
 
 
 class TtsGenerateAudioFunctionNotFound(Exception):
+    """
+    You must provide a callBack to the TTS
+    """
     pass
 
 
 class FailToLoadSoundFile(Exception):
+    """
+    Fail while truing to load the sound file.
+    """
     pass
 
 
 class TTSModule(object):
+    """
+    Mother class of TTS module. Handle:
+    - Cache: call cache object to create file, delete file, check if file exist
+    - Player: call the default player to play the generated file
+    """
 
     def __init__(self, **kwargs):
-        """
-        Mother class of TTS module. Handle:
-        - Cache: call cache object to create file, delete file, check if file exist
-        - Player: call the default player to play the generated file
-        """
+
         # set parameter from what we receive from the settings
         self.cache = kwargs.get('cache', False)
         self.language = kwargs.get('language', None)
@@ -54,7 +66,6 @@ class TTSModule(object):
     def play_audio(self):
         """
         Play the audio file
-        :return:
         """
         Mplayer.play(self.file_path)
 
@@ -62,8 +73,11 @@ class TTSModule(object):
         """
         Generate an audio file from <words> if not already in cache and call the Player to play it
         :param words: Sentence text from which we want to generate an audio file
+        :type words: String
         :param generate_audio_function_from_child: The child function to generate a file if necessary
-        :return:
+        :type generate_audio_function_from_child; Callback function
+
+        .. raises:: TtsGenerateAudioFunctionNotFound
         """
         if generate_audio_function_from_child is None:
             raise TtsGenerateAudioFunctionNotFound
@@ -120,7 +134,6 @@ class TTSModule(object):
     def is_file_already_in_cache(self):
         """
         Return true if the file to generate has already been generated before
-        :return:
         """
         # generate sub folder
         FileManager.create_directory(self.base_cache_path)

+ 1 - 2
core/TriggerLauncher.py

@@ -24,5 +24,4 @@ class TriggerLauncher(object):
         trigger.parameters["callback"] = callback
         logger.debug("TriggerLauncher: Start trigger %s with parameters: %s" % (trigger.name, trigger.parameters))
         return Utils.get_dynamic_class_instantiation("trigger", trigger.name.capitalize(),
-                                                                 trigger.parameters)
-
+                                                     trigger.parameters)

+ 12 - 1
core/Utils.py

@@ -5,6 +5,11 @@ logger = logging.getLogger("kalliope")
 
 
 class ModuleNotFoundError(Exception):
+    """
+    The module can not been found
+
+    .. notes: Check the case: must be in lower case.
+    """
     pass
 
 
@@ -55,7 +60,13 @@ class Utils(object):
 
     @classmethod
     def get_dynamic_class_instantiation(cls, package_name, module_name, parameters=None):
-
+        """
+        Load a python class dynamically
+        :param package_name: name of the package where we will find the module to load (neurons, tts, stt, trigger)
+        :param module_name: name of the module from the package_name to load
+        :param parameters:  dict parameters to send as argument to the module
+        :return:
+        """
         logger.debug("Run plugin %s with parameter %s" % (module_name, parameters))
         mod = __import__(package_name, fromlist=[module_name])
         try:

+ 0 - 2
kalliope.py

@@ -22,7 +22,6 @@ def signal_handler(signal, frame):
     Used to catch a keyboard signal like Ctrl+C in order to kill the kalliope program
     :param signal: signal handler
     :param frame: execution frame
-    :return:
     """
     print "\n"
     Utils.print_info("Ctrl+C pressed. Killing Kalliope")
@@ -95,7 +94,6 @@ def configure_logging(debug=None):
     """
     Prepare log folder in current home directory
     :param debug: If true, set the lof level to debug
-    :return:
     """
     logger = logging.getLogger("kalliope")
     logger.propagate = False

+ 10 - 0
neurons/gmail_checker/gmail_checker.py

@@ -57,7 +57,15 @@ class Gmail_checker(NeuronModule):
 
     @staticmethod
     def try_parse(header, encoding):
+        """
+        Verifying the Encoding and return unicode
+
+        :param header: the header to decode
+        :param encoding: the targeted encoding
+        :return: either 'ASCII' or 'ISO-8859-1' or 'UTF-8'
 
+        .. raises:: UnicodeDecodeError
+        """
         if encoding is None:
             encoding = 'ASCII'
         try:
@@ -72,6 +80,8 @@ class Gmail_checker(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: MissingParameterException
         """
         if self.username is None:
             raise MissingParameterException("Username parameter required")

+ 3 - 0
neurons/kill_switch/kill_switch.py

@@ -4,6 +4,9 @@ from core.NeuronModule import NeuronModule
 
 
 class Kill_switch(NeuronModule):
+    """
+    Class used to exit Kalliope process from system command
+    """
     def __init__(self, **kwargs):
         super(Kill_switch, self).__init__(**kwargs)
         sys.exit()

+ 10 - 2
neurons/neurotransmitter/neurotransmitter.py

@@ -19,6 +19,11 @@ class Neurotransmitter(NeuronModule):
             self.get_audio_from_stt(callback=self.callback)
 
     def callback(self, audio):
+        """
+        The callback used by the STT module to get the linked synapse
+
+        :param audio: the audio to play by STT
+        """
         logger.debug("Neurotransmitter, receiver audio from STT: %s" % audio)
         # print self.links
         # set a bool to know if we have found a valid answer
@@ -35,9 +40,12 @@ class Neurotransmitter(NeuronModule):
 
     def _links_content_ok(self):
         """
-        Check the content of the links parameter
-        :return:
+        Check if received links are ok to perform operations
+        :return: true if links are ok, raise an exception otherwise
+
+        .. raises:: MissingParameterException
         """
+
         if self.links is None:
             raise MissingParameterException("links parameter required and must contain at least one link")
         if self.default is None:

+ 2 - 0
neurons/openweathermap/Openweathermap.py

@@ -116,6 +116,8 @@ class Openweathermap(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: NotImplementedError
         """
         if self.api_key is None:
             raise NotImplementedError("OpenWeatherMap neuron needs an api_key")

+ 4 - 3
neurons/push_message/Push_message.py

@@ -14,7 +14,6 @@ class Push_message(NeuronModule):
         :param message: Message to send
         :param api_key: The Pushetta service secret token
         :param channel_name: Pushetta channel name
-        :return:
         """
         super(Push_message, self).__init__(**kwargs)
 
@@ -24,13 +23,15 @@ class Push_message(NeuronModule):
 
         # check if parameters have been provided
         if self._is_parameters_ok():
-            p = Pushetta( self.api_key)
+            p = Pushetta(self.api_key)
             p.pushMessage(self.channel_name, self.message)
 
     def _is_parameters_ok(self):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: NotImplementedError
         """
         if self.message is None:
             raise NotImplementedError("Pushetta neuron needs message to send")
@@ -39,4 +40,4 @@ class Push_message(NeuronModule):
         if self.channel_name is None:
             raise NotImplementedError("Pushetta neuron needs channel_name")
 
-        return True
+        return True

+ 2 - 0
neurons/say/say.py

@@ -14,6 +14,8 @@ class Say(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: MissingParameterException
         """
         if self.message is None:
             raise MissingParameterException("You must specify a message string or a list of messages as parameter")

+ 2 - 0
neurons/script/script.py

@@ -18,6 +18,8 @@ class Script(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: MissingParameterException, InvalidParameterException
         """
         if self.path is None:
             raise MissingParameterException("You must provide a script path.")

+ 10 - 0
neurons/shell/shell.py

@@ -8,6 +8,11 @@ logger = logging.getLogger("kalliope")
 
 
 class AsyncShell(threading.Thread):
+    """
+    Class used to run an asynchrone Shell command
+
+    .. notes:: Impossible to get the success code of the command
+    """
     def __init__(self, cmd):
         self.stdout = None
         self.stderr = None
@@ -24,6 +29,9 @@ class AsyncShell(threading.Thread):
 
 
 class Shell(NeuronModule):
+    """
+    Run a shell command in a synchron mode
+    """
     def __init__(self, **kwargs):
         super(Shell, self).__init__(**kwargs)
 
@@ -52,6 +60,8 @@ class Shell(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: MissingParameterException
         """
         if self.cmd is None:
             raise MissingParameterException("cmd parameter required")

+ 8 - 8
neurons/sleep/sleep.py

@@ -12,12 +12,12 @@ class Sleep(NeuronModule):
         if self._is_parameters_ok():
             time.sleep(self.seconds)
 
-        def _is_parameters_ok(self):
-            """
-            Check if received parameters are ok to perform operations in the neuron
-            :return: true if parameters are ok, raise an exception otherwise
-            """
-            if self.seconds is None:
-                raise MissingParameterException("You must set a number of seconds as parameter")
-
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
 
+        .. raises:: MissingParameterException
+        """
+        if self.seconds is None:
+            raise MissingParameterException("You must set a number of seconds as parameter")

+ 0 - 3
neurons/systemdate/systemdate.py

@@ -1,4 +1,3 @@
-#!/usr/bin/python
 import time
 
 from core.NeuronModule import NeuronModule
@@ -12,8 +11,6 @@ class Systemdate(NeuronModule):
             cache = False
         super(Systemdate, self).__init__(cache=cache, **kwargs)
 
-
-
         # local time and date
         hour = time.strftime("%H")          # Hour (24-hour clock) as a decimal number [00,23].
         minute = time.strftime("%M")        # Minute as a decimal number [00,59].

+ 2 - 0
neurons/tasker_autoremote/tasker_autoremote.py

@@ -30,6 +30,8 @@ class Tasker_autoremote(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: MissingParameterException
         """
         if self.key is None:
             raise MissingParameterException("key parameter required")

+ 2 - 0
neurons/twitter/Twitter.py

@@ -32,6 +32,8 @@ class Twitter(NeuronModule):
         """
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: InvalidParameterException
         """
         if self.consumer_key is None:
             raise InvalidParameterException("Twitter needs a consumer_key")

+ 4 - 2
neurons/wake_on_lan/Wake_on_lan.py

@@ -31,8 +31,10 @@ class Wake_on_lan(NeuronModule):
 
     def _is_parameters_ok(self):
         """
-        Check if received parameters are ok to perform operations in the neuron
-        :return: true if parameters are ok, raise an exception otherwise
+            Check if received parameters are ok to perform operations in the neuron
+            :return: true if parameters are ok, raise an exception otherwise
+
+            .. raises:: InvalidParameterException, MissingParameterException
         """
         # check we provide a mac address
         if self.mac_address is None:

+ 5 - 2
neurons/wikipedia/Wikipedia.py

@@ -41,7 +41,7 @@ class Wikipedia(NeuronModule):
                 self.may_refer = list(set(self.may_refer))
                 self.returncode = "DisambiguationError"
                 summary = ""
-            except wikipedia.exceptions.PageError, e:
+            except wikipedia.exceptions.PageError:
                 # Exception raised when no Wikipedia matched a query.
                 self.returncode = "PageError"
                 summary = ""
@@ -58,8 +58,11 @@ class Wikipedia(NeuronModule):
     def _is_parameters_ok(self):
         """
         Check if received parameters are ok to perform operations in the neuron
-        :return:
+        :return: true if parameters are ok, raise an exception otherwise
+
+        .. raises:: InvalidParameterException
         """
+
         if self.query is None:
             raise InvalidParameterException("Wikipedia needs a query")
         if self.language is None:

+ 4 - 4
stt/apiai/Apiai.py

@@ -14,10 +14,6 @@ class Apiai(OrderListener):
         """
         OrderListener.__init__(self)
 
-        """
-        Start recording the microphone
-        :return:
-        """
         # callback function to call after the translation speech/tex
         self.callback = callback
         # obtain audio from the microphone
@@ -46,6 +42,10 @@ class Apiai(OrderListener):
             Utils.print_danger("Could not request results from Apiai Speech Recognition service; {0}".format(e))
 
     def _analyse_audio(self, audio):
+        """
+        Confirm the audio exists annd run it in a Callback
+        :param audio: the captured audio
+        """
         # if self.main_controller is not None:
         #     self.main_controller.analyse_order(audio)
         if self.callback is not None:

+ 5 - 4
stt/bing/Bing.py

@@ -14,10 +14,6 @@ class Bing(OrderListener):
         """
         OrderListener.__init__(self)
 
-        """
-        Start recording the microphone
-        :return:
-        """
         # callback function to call after the translation speech/tex
         self.callback = callback
         # obtain audio from the microphone
@@ -45,6 +41,11 @@ class Bing(OrderListener):
             Utils.print_danger("Could not request results from Bing Speech Recognition service; {0}".format(e))
 
     def _analyse_audio(self, audio):
+        """
+        Confirm the audio exists annd run it in a Callback
+        :param audio: the captured audio
+        """
+
         # if self.main_controller is not None:
         #     self.main_controller.analyse_order(audio)
         if self.callback is not None:

+ 5 - 4
stt/google/Google.py

@@ -14,10 +14,6 @@ class Google(OrderListener):
         """
         OrderListener.__init__(self)
 
-        """
-        Start recording the microphone
-        :return:
-        """
         # callback function to call after the translation speech/tex
         self.callback = callback
         # obtain audio from the microphone
@@ -48,6 +44,11 @@ class Google(OrderListener):
             Utils.print_danger("Could not request results from Google Speech Recognition service; {0}".format(e))
 
     def _analyse_audio(self, audio):
+        """
+        Confirm the audio exists annd run it in a Callback
+        :param audio: the captured audio
+        """
+
         # if self.main_controller is not None:
         #     self.main_controller.analyse_order(audio)
         if self.callback is not None:

+ 8 - 13
stt/houndify/Houndify.py

@@ -14,10 +14,6 @@ class Houndify(OrderListener):
         """
         OrderListener.__init__(self)
 
-        """
-        Start recording the microphone
-        :return:
-        """
         # callback function to call after the translation speech/tex
         self.callback = callback
         # obtain audio from the microphone
@@ -30,14 +26,13 @@ class Houndify(OrderListener):
 
         # recognize speech using Houndify Speech Recognition
         try:
-
-
-            id = kwargs.get('client_id', None)
+            client_id = kwargs.get('client_id', None)
             key = kwargs.get('key', None)
             language = kwargs.get('language', "en-US")
             show_all = kwargs.get('show_all', False)
 
-            captured_audio = r.recognize_houndify(audio, client_id=id, client_key=key, language=language, show_all=show_all)
+            captured_audio = r.recognize_houndify(audio, client_id=client_id, client_key=key,
+                                                  language=language, show_all=show_all)
             Utils.print_success("Houndify Speech Recognition thinks you said %s" % captured_audio)
             self._analyse_audio(captured_audio)
 
@@ -47,12 +42,12 @@ class Houndify(OrderListener):
             Utils.print_danger("Could not request results from Houndify Speech Recognition service; {0}".format(e))
 
     def _analyse_audio(self, audio):
+        """
+            Confirm the audio exists annd run it in a Callback
+            :param audio: the captured audio
+        """
+
         # if self.main_controller is not None:
         #     self.main_controller.analyse_order(audio)
         if self.callback is not None:
             self.callback(audio)
-
-
-
-
-

+ 5 - 4
stt/wit/Wit.py

@@ -14,10 +14,6 @@ class Wit(OrderListener):
         """
         OrderListener.__init__(self)
 
-        """
-        Start recording the microphone
-        :return:
-        """
         # callback function to call after the translation speech/tex
         self.callback = callback
         # obtain audio from the microphone
@@ -43,6 +39,11 @@ class Wit(OrderListener):
             Utils.print_danger("Could not request results from Wit.ai Speech Recognition service; {0}".format(e))
 
     def _analyse_audio(self, audio):
+        """
+        Confirm the audio exists annd run it in a Callback
+        :param audio: the captured audio
+        """
+
         # if self.main_controller is not None:
         #     self.main_controller.analyse_order(audio)
         if self.callback is not None:

+ 4 - 20
test.py

@@ -10,24 +10,8 @@ logger.setLevel(logging.DEBUG)
 
 
 brain = BrainLoader.get_brain()
-
-brain2 = BrainLoader.get_brain()
-brain3 = BrainLoader.get_brain()
-brain4 = BrainLoader.get_brain()
-
-
-print brain is brain2
-print brain is brain3
-print brain is brain4
-print brain4 is brain2
-
-set = SettingLoader.get_settings()
-set2 = SettingLoader.get_settings()
-set3 = SettingLoader.get_settings()
-set4 = SettingLoader.get_settings()
-
-print set is set2
-print set is set3
-print set is set4
-print set3 is set2
+print brain.brain_yaml
+for synapse in brain.synapses:
+    print "test"
+    print synapse.name
 

+ 0 - 1
trigger/snowboy/snowboydecoder.py

@@ -114,7 +114,6 @@ class HotwordDetector(object):
             frames_per_buffer=2048,
             stream_callback=audio_callback)
 
-
     def start(self, detected_callback=play_audio_file,
               interrupt_check=lambda: False,
               sleep_time=0.03):

+ 24 - 0
tts/acapela/acapela.py

@@ -21,11 +21,19 @@ class Acapela(TTSModule):
             raise MissingTTSParameter("voice parameter is required by the Acapela TTS")
 
     def say(self, words):
+        """
+        :param words: The sentence to say
+        """
 
         self.generate_and_play(words, self._generate_audio_file)
 
     def _generate_audio_file(self):
+        """
+        Generic method used as a Callback in TTSModule
+            - must provided the audio file and write it on the disk
 
+        .. raises:: FailToLoadSoundFile
+        """
         # Prepare payload
         payload = self.get_payload()
 
@@ -48,6 +56,12 @@ class Acapela(TTSModule):
         FileManager.write_in_file(self.file_path, r.content)
 
     def get_payload(self):
+        """
+        Generic method used load the payload used to acces the remote api
+
+        :return: Payload to use to access the remote api
+        """
+
         return {
             "MyLanguages": self.language,
             "MySelectedVoice": self.voice,
@@ -58,6 +72,16 @@ class Acapela(TTSModule):
 
     @staticmethod
     def get_audio_link(url, payload, timeout_expected=TTS_TIMEOUT_SEC):
+        """
+        Return the audio link
+
+        :param url: the url to access
+        :param payload: the payload to use to acces the remote api
+        :param timeout_expected: timeout before the post request is cancel
+        :return: the audio link
+        :rtype: String
+        """
+
         r = requests.post(url, payload, timeout=timeout_expected)
         data = r.content
         return re.search("(?P<url>https?://[^\s]+).mp3", data).group(0)

+ 15 - 0
tts/googletts/googletts.py

@@ -16,10 +16,19 @@ class Googletts(TTSModule):
         super(Googletts, self).__init__(**kwargs)
 
     def say(self, words):
+        """
+        :param words: The sentence to say
+        """
 
         self.generate_and_play(words, self._generate_audio_file)
 
     def _generate_audio_file(self):
+        """
+        Generic method used as a Callback in TTSModule
+            - must provided the audio file and write it on the disk
+
+        .. raises:: FailToLoadSoundFile
+        """
 
         # Prepare payload
         payload = self.get_payload()
@@ -40,6 +49,12 @@ class Googletts(TTSModule):
         FileManager.write_in_file(self.file_path, r.content)
 
     def get_payload(self):
+        """
+        Generic method used load the payload used to access the remote api
+
+        :return: Payload to use to access the remote api
+        """
+
         return {
             "q": self.words,
             "tl": self.language,

+ 10 - 2
tts/pico2wave/pico2wave.py

@@ -15,10 +15,20 @@ class Pico2wave(TTSModule):
         super(Pico2wave, self).__init__(**kwargs)
 
     def say(self, words):
+        """
+        :param words: The sentence to say
+        """
 
         self.generate_and_play(words, self._generate_audio_file)
 
     def _generate_audio_file(self):
+        """
+        Generic method used as a Callback in TTSModule
+            - must provided the audio file and write it on the disk
+
+        .. raises:: FailToLoadSoundFile
+        """
+
         pico2wave_exec_path = ["/usr/bin/pico2wave"]
 
         # pico2wave needs that the file path ends with .wav
@@ -37,5 +47,3 @@ class Pico2wave(TTSModule):
 
         # remove the extension .wav
         os.rename(tmp_path, self.file_path)
-
-

+ 14 - 1
tts/voicerss/voicerss.py

@@ -16,11 +16,19 @@ class Voicerss(TTSModule):
         super(Voicerss, self).__init__(**kwargs)
 
     def say(self, words):
+        """
+        :param words: The sentence to say
+        """
 
         self.generate_and_play(words, self._generate_audio_file)
 
     def _generate_audio_file(self):
+        """
+        Generic method used as a Callback in TTSModule
+            - must provided the audio file and write it on the disk
 
+        .. raises:: FailToLoadSoundFile
+        """
         # Prepare payload
         payload = self.get_payload()
 
@@ -40,9 +48,14 @@ class Voicerss(TTSModule):
         FileManager.write_in_file(self.file_path, r.content)
 
     def get_payload(self):
+        """
+        Generic method used load the payload used to acces the remote api
+
+        :return: Payload to use to access the remote api
+        """
+
         return {
             "src": self.words,
             "hl": self.language,
             "c": "mp3"
         }
-

+ 19 - 2
tts/voxygen/voxygen.py

@@ -3,7 +3,7 @@ import logging
 import requests
 
 from core import FileManager
-from core.TTS.TTSModule import TTSModule, MissingTTSParameter, FailToLoadSoundFile
+from core.TTS.TTSModule import TTSModule, MissingTTSParameter
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
@@ -24,9 +24,20 @@ class Voxygen(TTSModule):
             raise MissingTTSParameter("voice parameter is required by the Voxygen TTS")
 
     def say(self, words):
+        """
+        :param words: The sentence to say
+        """
+
         self.generate_and_play(words, self._generate_audio_file)
 
     def _generate_audio_file(self):
+        """
+        Generic method used as a Callback in TTSModule
+            - must provided the audio file and write it on the disk
+
+        .. raises:: FailToLoadSoundFile
+        """
+
         payload = self.get_payload(self.voice, self.words)
 
         # getting the mp3
@@ -45,8 +56,14 @@ class Voxygen(TTSModule):
 
     @staticmethod
     def get_payload(voice, words):
+        """
+        Generic method used load the payload used to access the remote api
+
+        :return: Payload to use to access the remote api
+        """
+
         return {
             "method": "redirect",
             "text": words,
             "voice": voice
-        }
+        }