Copy plugins to module instead of kludgy import

This commit is contained in:
thatmattlove 2021-10-04 01:38:44 -07:00
parent 3c073878fa
commit 8013c48ae9
5 changed files with 13 additions and 9 deletions

View file

@ -16,6 +16,7 @@ InputPluginReturn = t.Union[None, bool]
class InputPlugin(HyperglassPlugin, DirectivePlugin): class InputPlugin(HyperglassPlugin, DirectivePlugin):
"""Plugin to validate user input prior to running commands.""" """Plugin to validate user input prior to running commands."""
_type = "input"
failure_reason: t.Optional[str] = None failure_reason: t.Optional[str] = None
def validate(self, query: "Query") -> InputPluginReturn: def validate(self, query: "Query") -> InputPluginReturn:

View file

@ -21,6 +21,8 @@ OutputType = Union["OutputDataModel", Series[str]]
class OutputPlugin(HyperglassPlugin, DirectivePlugin, PlatformPlugin): class OutputPlugin(HyperglassPlugin, DirectivePlugin, PlatformPlugin):
"""Plugin to interact with device command output.""" """Plugin to interact with device command output."""
_type = "output"
def process(self, *, output: OutputType, query: "Query") -> OutputType: def process(self, *, output: OutputType, query: "Query") -> OutputType:
"""Process or manipulate output from a device.""" """Process or manipulate output from a device."""
log.warning("Output plugin '{}' has not implemented a 'process()' method", self.name) log.warning("Output plugin '{}' has not implemented a 'process()' method", self.name)

View file

@ -0,0 +1,4 @@
# Ignore all files as they're imported at runtime.
*
!__init__.py
!.gitignore

View file

View file

@ -2,22 +2,18 @@
# Standard Library # Standard Library
import sys import sys
import shutil
import typing as t import typing as t
from inspect import isclass, getmembers from inspect import isclass, getmembers
from pathlib import Path from pathlib import Path
from importlib.util import module_from_spec, spec_from_file_location from importlib.util import module_from_spec, spec_from_file_location
# Project
from hyperglass.log import log
# Local # Local
from . import _builtin from . import _builtin
from ._input import InputPlugin from ._input import InputPlugin
from ._output import OutputPlugin from ._output import OutputPlugin
from ._manager import InputPluginManager, OutputPluginManager from ._manager import InputPluginManager, OutputPluginManager
_PLUGIN_GLOBALS = {"InputPlugin": InputPlugin, "OutputPlugin": OutputPlugin, "log": log}
def _is_class(module: t.Any, obj: object) -> bool: def _is_class(module: t.Any, obj: object) -> bool:
if isclass(obj): if isclass(obj):
@ -50,11 +46,12 @@ def _register_from_module(module: t.Any, **kwargs: t.Any) -> t.Tuple[str, ...]:
def _module_from_file(file: Path) -> t.Any: def _module_from_file(file: Path) -> t.Any:
"""Import a plugin module from its file Path object.""" """Import a plugin module from its file Path object."""
name = file.name.split(".")[0] plugins_dir = Path(__file__).parent / "external"
spec = spec_from_file_location(f"hyperglass.plugins.external.{name}", file) dst = plugins_dir / f"imported_{file.name}"
shutil.copy2(file, dst)
name = f"imported_{file.name.split('.')[0]}"
spec = spec_from_file_location(f"hyperglass.plugins.external.{name}", dst)
module = module_from_spec(spec) module = module_from_spec(spec)
for k, v in _PLUGIN_GLOBALS.items():
setattr(module, k, v)
spec.loader.exec_module(module) spec.loader.exec_module(module)
return module return module