knext parameter as dictionary object

Dear KNIMErs and developers,

I am exploring the new python based KNIME extension. I need to generate the fields (parameters) in node configuration dialogue from a JSON file. I’m first parsing the JSON attribute and its values into a python list and then based on type of value, generate corresponding knext.parameter. This is how it is done in my code example below.

  1. Parse the JSON attribute and value as lists.
import json
    keys = []
    values = []
    with open('config_json.json', "r") as read_file:
        data = json.load(read_file)

     for key, value in data.items():
        keys.append(key)
        values.append(value)
  1. Depending upon the attribute value type generate knext parameter. e.g.
import knime.extension as knext

       if isinstance(value, str):
                aa = knext.StringParameter(key[idx], key[idx] ,value)
       if isinstance(value, float):
                bb = knext.DoubleParameter(key[idx], key[idx] ,value)

This works fine and configuration dialogue is rendered with correct parameters. However, Since content of JSON file can vary I have no way of knowing how many parameter object I would need. I thought of using dictionary to solve this issue. Something like below.

import knime.extension as knext

variable_dict = {}
    for k, v in enumerate(value):
        if isinstance(v, str):
            variable_dict[k] = knext.StringParameter(k, k ,v)
         if isinstance(v, float):
                variable_dict[k]  = knext.DoubleParameter(k, k,v)

But this doesn’t work and parameters fields are not rendered in configuration dialogue.

I’m looking for suggestion, if this is something feasible or how to do it?

Thanks.

Bilal

Hi Bilal,

Welcome to the KNIME Forum! Cool that you are exploring the Python-based KNIME extensions. Generating dialogs based on dynamic information is not a basic use case (and therefore not really documented) but it is possible with parameter groups. I hacked together a small example:

@knext.parameter_group("Parameter Group")
class DynamicParameterGroup:

    def __init__(self, parameter_def):
        # NOTE: This is just an example
        # You can write any custom code to generate parameters
        for name, default_value in parameter_def.items():
            # Use __dict__ to access the object attributes with a variable name
            self.__dict__[name] = knext.IntParameter(
                    label=name, description=name, default_value=default_value
            )

@knext.node(
    name="Dynamic Parameters Node",
    node_type=knext.NodeType.MANIPULATOR,
    icon_path="icon.png",
    category=node_category,
)
class DynamicParametersNode:

    params = DynamicParameterGroup({
        "foo": 1,
        "bar": 100,
        "car": 42,
    })

    def configure(self, config_context):
        LOGGER.warning(self.params.__parameters__)

    def execute(self, exec_context):
        LOGGER.warning(self.params.__parameters__)

This should work but maybe there are more elegant solutions.

PS: If you are interested in the details: The code which extracts the parameters for nodes lives here.

2 Likes

Thanks Benjamin for prompt reply :slightly_smiling_face: @bwilhelm,

This looks like what I might need. While trying your example I stumble upon the following error message.

AttributeError: 'IntParameter' object has no attribute '_name'

Probably I missed something from your example?

Hi @nizamibilal1064,

Yes, the example does not work for KNIME AP before version 5.1. Sorry, I did not check that. It looks to be related to this commit. Is it feasible for you to use 5.1?

Thank you Benjamin @bwilhelm. It works with KAP 5.1.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.