Skip to content

molfeat.plugins

BaseFactory(group, name, load=True)

Return the plugin class registered under a given entry point group and name.

Parameters:

Name Type Description Default
group str

entry point group

required
name str

entry point name

required
load bool

if True, load the matched entry point and return the loaded resource instead of the entry point itself.

True

Return: the plugin class Raises: MissingEntryPointError: entry point was not registered MultipleEntryPointError: entry point could not be uniquely resolved LoadingEntryPointError: entry point could not be loaded

Source code in molfeat/plugins/factories.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def BaseFactory(group: str, name: str, load: bool = True) -> Union[EntryPoint, Any]:
    """Return the plugin class registered under a given entry point group and name.

    Args:
        group: entry point group
        name: entry point name
        load: if True, load the matched entry point and return the loaded resource instead of the entry point itself.
    Return:
        the plugin class
    Raises:
        MissingEntryPointError: entry point was not registered
        MultipleEntryPointError: entry point could not be uniquely resolved
        LoadingEntryPointError: entry point could not be loaded
    """
    # circular import
    from .entry_point import get_entry_point, load_entry_point

    if load is True:
        return load_entry_point(group, name)

    return get_entry_point(group, name)

CalculatorFactory(entry_point_name, load=True, entry_point_group=None)

Return the SerializableCalculator sub class registered under the given entry point.

Parameters:

Name Type Description Default
entry_point_name str

the entry point name.

required
load bool

if True, load the matched entry point and return the loaded resource instead of the entry point itself.

True
entry_point_group Optional[str]

the optional entry point group to use

None
Return

sub class of 🇵🇾class:~molfeat.calc.SerializableCalculator

Source code in molfeat/plugins/factories.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
def CalculatorFactory(
    entry_point_name: str,
    load: bool = True,
    entry_point_group: Optional[str] = None,
) -> Union[EntryPoint, Type["SerializableCalculator"], Callable]:
    """Return the `SerializableCalculator` sub class registered under the given entry point.

    Args:
        entry_point_name: the entry point name.
        load: if True, load the matched entry point and return the loaded resource instead of the entry point itself.
        entry_point_group: the optional entry point group to use

    Return:
        sub class of :py:class:`~molfeat.calc.SerializableCalculator`
    """
    from molfeat.calc import SerializableCalculator

    if entry_point_group is None:
        entry_point_group = "molfeat.calc"
    entry_point = BaseFactory(entry_point_group, entry_point_name, load=load)
    valid_classes = (SerializableCalculator,)

    if not load:
        return entry_point

    # if the entry point is a module, nothing to do
    if ismodule(entry_point):
        return entry_point
    if isclass(entry_point) and issubclass(entry_point, valid_classes):
        return entry_point

    raise_invalid_type_error(entry_point_name, entry_point_group, valid_classes)

DefaultFactory(entry_point_name, load=True, entry_point_group=None)

Return the Default factory for extending capabilities given a specific module.

Parameters:

Name Type Description Default
entry_point_name str

the entry point name.

required
load bool

if True, load the matched entry point and return the loaded resource instead of the entry point itself.

True
entry_point_group str

the optional entry point group to use

None

Returns:

Type Description
Union[EntryPoint, Type[PretrainedMolTransformer], Callable]

sub class or module of

Raise

InvalidEntryPointTypeError: if the type of the loaded entry point is invalid.

Source code in molfeat/plugins/factories.py
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
def DefaultFactory(
    entry_point_name: str,
    load: bool = True,
    entry_point_group: str = None,
) -> Union[EntryPoint, Type["PretrainedMolTransformer"], Callable]:
    """Return the Default factory for extending capabilities given a specific module.

    Args:
        entry_point_name: the entry point name.
        load: if True, load the matched entry point and return the loaded resource instead of the entry point itself.
        entry_point_group: the optional entry point group to use

    Returns:
        sub class or module of

    Raise:
        InvalidEntryPointTypeError: if the type of the loaded entry point is invalid.
    """

    if entry_point_group is None:
        entry_point_group = "molfeat"
    entry_point = BaseFactory(entry_point_group, entry_point_name, load=load)

    if not load:
        return entry_point
    # if the entry point is a module, nothing to do
    if ismodule(entry_point):
        return entry_point
    raise_invalid_type_error(entry_point_name, entry_point_group, ())

PretrainedTransformerFactory(entry_point_name, load=True, entry_point_group=None)

Return the PretrainedMolTransformer sub class registered under the given entry point.

Parameters:

Name Type Description Default
entry_point_name str

the entry point name.

required
load bool

if True, load the matched entry point and return the loaded resource instead of the entry point itself.

True
entry_point_group Optional[str]

the optional entry point group to use

None

Returns:

Type Description
Union[EntryPoint, Type[PretrainedMolTransformer], Callable]

sub class of 🇵🇾class:~molfeat.trans.pretrained.PretrainedMolTransformer

Raise

InvalidEntryPointTypeError: if the type of the loaded entry point is invalid.

Source code in molfeat/plugins/factories.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
def PretrainedTransformerFactory(
    entry_point_name: str,
    load: bool = True,
    entry_point_group: Optional[str] = None,
) -> Union[EntryPoint, Type["PretrainedMolTransformer"], Callable]:
    """Return the PretrainedMolTransformer sub class registered under the given entry point.

    Args:
        entry_point_name: the entry point name.
        load: if True, load the matched entry point and return the loaded resource instead of the entry point itself.
        entry_point_group: the optional entry point group to use

    Returns:
        sub class of :py:class:`~molfeat.trans.pretrained.PretrainedMolTransformer`

    Raise:
        InvalidEntryPointTypeError: if the type of the loaded entry point is invalid.
    """
    from molfeat.trans import MoleculeTransformer
    from molfeat.trans.pretrained import PretrainedMolTransformer

    if entry_point_group is None:
        entry_point_group = "molfeat.trans.pretrained"
    entry_point = BaseFactory(entry_point_group, entry_point_name, load=load)
    valid_classes = (PretrainedMolTransformer, MoleculeTransformer)

    if not load:
        return entry_point
    # if the entry point is a module, nothing to do
    if ismodule(entry_point):
        return entry_point
    if isclass(entry_point) and issubclass(entry_point, valid_classes):
        return entry_point

    raise_invalid_type_error(entry_point_name, entry_point_group, valid_classes)

TransformerFactory(entry_point_name, load=True, entry_point_group=None)

Return the MoleculeTransformer sub class registered under the given entry point.

Parameters:

Name Type Description Default
entry_point_name str

the entry point name.

required
load bool

if True, load the matched entry point and return the loaded resource instead of the entry point itself.

True
entry_point_group Optional[str]

the optional entry point group to use

None

Returns:

Type Description
Union[EntryPoint, Type[MoleculeTransformer], Callable]

sub class of 🇵🇾class:~molfeat.trans.MoleculeTransformer

Raise

InvalidEntryPointTypeError: if the type of the loaded entry point is invalid.

Source code in molfeat/plugins/factories.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
def TransformerFactory(
    entry_point_name: str,
    load: bool = True,
    entry_point_group: Optional[str] = None,
) -> Union[EntryPoint, Type["MoleculeTransformer"], Callable]:
    """Return the `MoleculeTransformer` sub class registered under the given entry point.

    Args:
        entry_point_name: the entry point name.
        load: if True, load the matched entry point and return the loaded resource instead of the entry point itself.
        entry_point_group: the optional entry point group to use

    Returns:
        sub class of :py:class:`~molfeat.trans.MoleculeTransformer`

    Raise:
        InvalidEntryPointTypeError: if the type of the loaded entry point is invalid.
    """
    from molfeat.trans import MoleculeTransformer
    from molfeat.trans import BaseFeaturizer

    if entry_point_group is None:
        entry_point_group = "molfeat.trans"
    entry_point = BaseFactory(entry_point_group, entry_point_name, load=load)
    valid_classes = (MoleculeTransformer, BaseFeaturizer)

    if not load:
        return entry_point

    # if the entry point is a module, nothing to do
    if ismodule(entry_point):
        return entry_point
    if isclass(entry_point) and issubclass(entry_point, valid_classes):
        return entry_point

    raise_invalid_type_error(entry_point_name, entry_point_group, valid_classes)

raise_invalid_type_error(entry_point_name, entry_point_group, valid_classes)

Raise an InvalidEntryPointTypeError with formatted message.

Parameters:

Name Type Description Default
entry_point_name str

name of the entry point

required
entry_point_group str

name of the entry point group

required
valid_classes Tuple[Any, ...]

tuple of valid classes for the given entry point group

required

Raises:

Type Description
InvalidEntryPointTypeError

always

Source code in molfeat/plugins/factories.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def raise_invalid_type_error(
    entry_point_name: str, entry_point_group: str, valid_classes: Tuple[Any, ...]
) -> NoReturn:
    """Raise an `InvalidEntryPointTypeError` with formatted message.

    Args:
        entry_point_name: name of the entry point
        entry_point_group: name of the entry point group
        valid_classes: tuple of valid classes for the given entry point group

    Raises:
        InvalidEntryPointTypeError: always
    """
    template = "entry point `{}` registered in group `{}` is invalid because its type is not one of the supported types ({})"
    args = (
        entry_point_name,
        entry_point_group,
        ", ".join([e.__name__ for e in valid_classes]),
    )
    raise InvalidEntryPointTypeError(template.format(*args))

get_entry_point(group, name)

Return an entry point with a given name within a specific group Args: group: the entry point group name: the name of the entry point

Source code in molfeat/plugins/entry_point.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def get_entry_point(group: str, name: str) -> EntryPoint:
    """
    Return an entry point with a given name within a specific group
    Args:
        group: the entry point group
        name: the name of the entry point
    """
    found = eps().select(group=group, name=name)
    if name not in found.names:
        raise MissingEntryPointError(f"Entry point '{name}' not found in group '{group}'")
    # If multiple entry points are found and they have different values we raise, otherwise if they all
    # correspond to the same value, we simply return one of them
    if len(found) > 1 and len(set(ep.value for ep in found)) != 1:
        raise MultipleEntryPointError(
            f"Multiple entry points '{name}' found in group '{group}': {found}"
        )
    return found[name]

get_entry_points(group)

Return a list of all the entry points within a specific group

Parameters:

Name Type Description Default
group str

the entry point group

required

Returns:

Type Description

a list of entry points

Source code in molfeat/plugins/entry_point.py
74
75
76
77
78
79
80
81
82
83
84
def get_entry_points(group: str):
    """
    Return a list of all the entry points within a specific group

    Args:
        group: the entry point group

    Returns:
        a list of entry points
    """
    return eps().select(group=group)

is_registered_entry_point(class_module, class_name, groups=None) cached

Verify whether the class with the given module and class name is a registered entry point.

Note

This function only checks whether the class has a registered entry point. It does explicitly not verify if the corresponding class is also importable. Use load_entry_point for this purpose instead.

Parameters:

Name Type Description Default
class_module str

the module of the class

required
class_name str

the name of the class

required
groups Optional[Sequence[str]]

optionally consider only these entry point groups to look for the class

None

Returns:

Type Description
bool

True if the class is a registered entry point, False otherwise.

Source code in molfeat/plugins/entry_point.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@functools.lru_cache(maxsize=100)
def is_registered_entry_point(
    class_module: str, class_name: str, groups: Optional[Sequence[str]] = None
) -> bool:
    """Verify whether the class with the given module and class name is a registered entry point.

    !!! note
        This function only checks whether the class has a registered entry point. It does explicitly not verify
        if the corresponding class is also importable. Use `load_entry_point` for this purpose instead.

    Args:
        class_module: the module of the class
        class_name: the name of the class
        groups: optionally consider only these entry point groups to look for the class

    Returns:
        True if the class is a registered entry point, False otherwise.
    """
    for group in eps().groups if groups is None else groups:
        for entry_point in get_entry_points(group):
            if class_module == entry_point.module and class_name == entry_point.attr:
                return True
    return False

load_entry_point(group, name)

Load the class registered under the entry point for a given name and group

Parameters:

Name Type Description Default
group str

the entry point group

required
name str

the name of the entry point

required

Returns:

Type Description
Any

class registered at the given entry point

Raises:

Type Description
MissingEntryPointError

if the entry point was not registered

MultipleEntryPointError

if the entry point could not be uniquely resolved

LoadingEntryPointError

if the entry point could not be loaded

Source code in molfeat/plugins/entry_point.py
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def load_entry_point(group: str, name: str) -> Any:
    """
    Load the class registered under the entry point for a given name and group

    Args:
        group: the entry point group
        name: the name of the entry point

    Returns:
        class registered at the given entry point

    Raises:
        MissingEntryPointError: if the entry point was not registered
        MultipleEntryPointError: if the entry point could not be uniquely resolved
        LoadingEntryPointError: if the entry point could not be loaded
    """
    entry_point = get_entry_point(group, name)

    try:
        loaded_entry_point = entry_point.load()
    except ImportError:
        raise LoadingEntryPointError(
            f"Failed to load entry point '{name}':\n{traceback.format_exc()}"
        )

    return loaded_entry_point

load_registered_plugins(add_submodules=True, groups=None, plugins=None, verbose=True)

Load all registered entry points by loading them with the corresponding factory and adding them to the corresponding module attribute.

Parameters:

Name Type Description Default
add_submodules bool

if True, add the loaded entry point to the corresponding module attribute.

True
groups Optional[List[str]]

if provided, only load entry points from the given groups.

None
plugins Optional[List[str]]

if provided, only load entry points or modules/classes that matches entry in the plugins list.

None
verbose bool

if True, log a warning if an entry point cannot be loaded.

True

Raises:

Type Description
EntryPointError

if any of the registered entry points cannot be loaded. This can happen if: * The entry point cannot uniquely be resolved * The resource registered at the entry point cannot be imported * The resource's type is incompatible with the entry point group that it is defined in.

Source code in molfeat/plugins/entry_point.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def load_registered_plugins(
    add_submodules: bool = True,
    groups: Optional[List[str]] = None,
    plugins: Optional[List[str]] = None,
    verbose: bool = True,
):
    """Load all registered entry points by loading them with the corresponding factory and adding them to the corresponding module attribute.

    Args:
        add_submodules: if True, add the loaded entry point to the corresponding module attribute.
        groups: if provided, only load entry points from the given groups.
        plugins: if provided, only load entry points or modules/classes that matches entry in the plugins list.
        verbose: if True, log a warning if an entry point cannot be loaded.

    Raises:
        EntryPointError: if any of the registered entry points cannot be loaded. This can happen if:
            * The entry point cannot uniquely be resolved
            * The resource registered at the entry point cannot be imported
            * The resource's type is incompatible with the entry point group that it is defined in.
    """
    for entry_point_group, factory in ENTRY_POINT_GROUP_FACTORYCLASS_MAPPING.items():
        if groups is not None and entry_point_group not in groups:
            continue
        entry_points = get_entry_points(entry_point_group)
        for entry_point in entry_points:
            try:
                loaded_module = factory(entry_point.name, entry_point_group=entry_point_group)
                if _is_valid_plugin(loaded_module, plugins):
                    setattr(
                        sys.modules[entry_point.group],
                        loaded_module.__name__,
                        loaded_module,
                    )
                    if add_submodules:
                        if not ismodule(loaded_module):
                            module_to_add = loaded_module.__module__
                        else:
                            module_to_add = loaded_module
                        sys.modules[f"{entry_point.group}.{entry_point.name}"] = module_to_add
            except AttributeError as e:
                if verbose:
                    logger.warning(
                        f"Could not load entry point {entry_point.name} from group {entry_point.group}"
                    )
                    logger.exception(e)

validate_registered_entry_points()

Validate all registered entry points by loading them with the corresponding factory.

Raises:

Type Description
EntryPointError

if any of the registered entry points cannot be loaded. This can happen if: * The entry point cannot uniquely be resolved * The resource registered at the entry point cannot be imported * The resource's type is incompatible with the entry point group that it is defined in.

Source code in molfeat/plugins/entry_point.py
131
132
133
134
135
136
137
138
139
140
141
142
143
def validate_registered_entry_points():
    """Validate all registered entry points by loading them with the corresponding factory.

    Raises:
        EntryPointError: if any of the registered entry points cannot be loaded. This can happen if:
            * The entry point cannot uniquely be resolved
            * The resource registered at the entry point cannot be imported
            * The resource's type is incompatible with the entry point group that it is defined in.
    """
    for entry_point_group, factory in ENTRY_POINT_GROUP_FACTORYCLASS_MAPPING.items():
        entry_points = get_entry_points(entry_point_group)
        for entry_point in entry_points:
            factory(entry_point.name)