From 13d837d457bb9fe6af7047f4005cba1597d32369 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:04:37 +0000 Subject: [PATCH] feat/SkillNetworkRequirements (#36) * feat/SkillNetworkRequirements * rename args for clariy * classproperty --- ovos_workshop/decorators/__init__.py | 5 +++ ovos_workshop/skills/ovos.py | 58 ++++++++++++++++++++++++++++ test/unittests/test_skill_classes.py | 50 ++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 test/unittests/test_skill_classes.py diff --git a/ovos_workshop/decorators/__init__.py b/ovos_workshop/decorators/__init__.py index e182dd0e..46b7da5e 100644 --- a/ovos_workshop/decorators/__init__.py +++ b/ovos_workshop/decorators/__init__.py @@ -24,3 +24,8 @@ def real_decorator(func): return func return real_decorator + + +class classproperty(property): + def __get__(self, owner_self, owner_cls): + return self.fget(owner_cls) diff --git a/ovos_workshop/skills/ovos.py b/ovos_workshop/skills/ovos.py index 4baa0b4a..db30570b 100644 --- a/ovos_workshop/skills/ovos.py +++ b/ovos_workshop/skills/ovos.py @@ -19,6 +19,30 @@ from ovos_workshop.resource_files import SkillResources from ovos_utils.dialog import get_dialog from ovos_utils.messagebus import create_wrapper +from ovos_workshop.decorators import classproperty + +from dataclasses import dataclass + + +@dataclass +class SkillNetworkRequirements: + # to ensure backwards compatibility the default values require internet before skill loading + # skills in the wild may assume this behaviour and require network on initialization + # any ovos aware skills should change these as appropriate + + # xxx_before_load is used by skills service + network_before_load: bool = True + internet_before_load: bool = True + + # requires_xxx is currently purely informative and not consumed by core + # this allows a skill to spec if it needs connectivity to handle utterances + requires_internet: bool = True + requires_network: bool = True + + # xxx_fallback is currently purely informative and not consumed by core + # this allows a skill to spec if it has a fallback for temporary offline events, eg, by having a cache + no_internet_fallback: bool = False + no_network_fallback: bool = False class OVOSSkill(MycroftSkill): @@ -46,6 +70,40 @@ def bind(self, bus): self.private_settings = PrivateSettings(self.skill_id) self.intent_layers.bind(self) + @classproperty + def network_requirements(self): + """ skill developers should override this if they do not require connectivity + + some examples: + + IOT skill that controls skills via LAN could return: + scans_on_init = True + SkillNetworkRequirements(internet_before_load=False, + network_before_load=scans_on_init, + requires_internet=False, + requires_network=True, + no_internet_fallback=True, + no_network_fallback=False) + + online search skill with a local cache: + has_cache = False + SkillNetworkRequirements(internet_before_load=not has_cache, + network_before_load=not has_cache, + requires_internet=True, + requires_network=True, + no_internet_fallback=True, + no_network_fallback=True) + + a fully offline skill: + SkillNetworkRequirements(internet_before_load=False, + network_before_load=False, + requires_internet=False, + requires_network=False, + no_internet_fallback=True, + no_network_fallback=True) + """ + return SkillNetworkRequirements() + def play_audio(self, filename): try: from mycroft.version import OVOS_VERSION_BUILD, OVOS_VERSION_MINOR, OVOS_VERSION_MAJOR diff --git a/test/unittests/test_skill_classes.py b/test/unittests/test_skill_classes.py new file mode 100644 index 00000000..04b9e54c --- /dev/null +++ b/test/unittests/test_skill_classes.py @@ -0,0 +1,50 @@ +import unittest +from ovos_workshop.decorators import classproperty +from ovos_workshop.skills.ovos import OVOSSkill, SkillNetworkRequirements + + +class OfflineSkill(OVOSSkill): + @classproperty + def network_requirements(self): + return SkillNetworkRequirements(internet_before_load=False, + network_before_load=False, + requires_internet=False, + requires_network=False, + no_internet_fallback=True, + no_network_fallback=True) + + +class LANSkill(OVOSSkill): + @classproperty + def network_requirements(self): + scans_on_init = True + return SkillNetworkRequirements(internet_before_load=False, + network_before_load=scans_on_init, + requires_internet=False, + requires_network=True, + no_internet_fallback=True, + no_network_fallback=False) + + +class TestSkill(unittest.TestCase): + + def test_class_property(self): + self.assertEqual(OfflineSkill.network_requirements, + SkillNetworkRequirements(internet_before_load=False, + network_before_load=False, + requires_internet=False, + requires_network=False, + no_internet_fallback=True, + no_network_fallback=True) + ) + self.assertEqual(LANSkill.network_requirements, + SkillNetworkRequirements(internet_before_load=False, + network_before_load=True, + requires_internet=False, + requires_network=True, + no_internet_fallback=True, + no_network_fallback=False) + ) + self.assertEqual(OVOSSkill.network_requirements, + SkillNetworkRequirements() + )