Modifier API#
The modifiers are defined as decorator functions that can modify a function and take additional input parameters. See documentation for functools.wraps. The modifiers can be applied to a node or a model. It is important to note that the modifier only sees the function rather than the node object, meaning modifiers do not have access to the node information. The decision is made to simplify the modifier definition. Modifying the function does not require the modifiers to handle the passing down of the node information properly, increasing the compatibility of chained modifiers.
Here is an example of a loop modifier:
def loop_input(parameter: str):
"""Modify function to iterate one given parameter.
:param list parameter: target parameter to loop
The target parameter name is changed to f"{param}_loop"
"""
def loop(func):
param_list = []
for param in signature(func).parameters.values():
if param.name == parameter:
param_list.append(Parameter(f"{param}_loop", kind=1))
else:
param_list.append(param)
new_sig = Signature(param_list)
@wraps(func)
def loop_wrapped(**kwargs):
"""Isolate the loop parameter and loop over the values."""
loop_values = kwargs.pop(f"{parameter}_loop")
return [func(**kwargs, **{parameter: value}) for value in loop_values]
loop_wrapped.__signature__ = new_sig
return loop_wrapped
loop.metadata = f"loop_input({repr(parameter)})"
return loop
The modifier takes an additional argument “parameter” and returns a modified function.
For a node, the equivalent function is :code:loop_input(parameter)(func)
.
The function signature is modified under the loop
function to indicate that the parameter
requires an iterable input. Under the loop_wrapped
function, the loop parameter is
isolated, and the function loops over the iterable to create a list result.
Notice that the loop_wrapped
function takes keyword-only arguments. The decision
is made to reduce the overhead of the function call. All nodes in the Model are supplied
with keyword-only arguments. See signature API for more information.
Note
mmodel requires modifiers to have a proper signature. If the modifier changes the
function signature, add __signature__
attribute with inspect.Signature
to the
wrapped function.
The metadata of the modifier is used to generate the string displayed in the metadata at the node and model level. The metadata is a string passed to the “metadata” attribute of the modifier function.
See modifier tutorial for how to use modifiers, and modifier reference </ref_modifier> for all available modifiers.