-
Notifications
You must be signed in to change notification settings - Fork 29
/
registry.py
48 lines (37 loc) · 1.85 KB
/
registry.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from pkgutil import ModuleInfo
from types import ModuleType
from typing import Callable, Iterator, List
from click import Command, Group
class Registry:
"""A registry for resources that are built-in or contributed by plugins."""
def __init__(self) -> None:
self._create_command_functions: List[Callable[[Group], Command]] = []
def register_subcommand(
self, create_command_function: Callable[[Group], Command]
) -> None:
self._create_command_functions.append(create_command_function)
def get_create_subcommand_functions(self) -> List[Callable[[Group], Command]]:
return self._create_command_functions[:]
def load_plugins(self) -> None:
"""Discover all plugins and register their resources.
Import each Python module within the stactools namespace package
and call the register_plugin function at its root (if it exists).
"""
import importlib
import pkgutil
import stactools
# From https://packaging.python.org/guides/creating-and-discovering-plugins/#using-namespace-packages # noqa
def iter_namespace(ns_pkg: ModuleType) -> Iterator[ModuleInfo]:
# Specifying the second argument (prefix) to iter_modules makes the
# returned name an absolute name instead of a relative one. This allows
# import_module to work without having to do additional modification to
# the name.
return pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + ".")
discovered_plugins = {
name: importlib.import_module(name)
for finder, name, ispkg in iter_namespace(stactools)
}
for name, module in discovered_plugins.items():
register_plugin = getattr(module, "register_plugin", None)
if register_plugin:
register_plugin(self)