This article explains a best practice for moving different portions of your Nom Nom App code into different files. Specifically it focuses on moving the portion of the code that controls the user interface to a different file, but the techniques described can be generalized and applied to any logical separations that you would like to have. It is assumed that the reader is already familiar with the information in the
Creating Your First Nom Nom App article.
Identify Code to Move
The highlighted portion of the sample app code below is the code that tells the Nominode how the user interface for the app should be rendered. In this example, we will explain how to move that code from the pkg/executable.py file to a different file within your app.
import logging
from nomnomdata.engine import Engine, Parameter, ParameterGroup
from nomnomdata.engine.parameters import Int, String
logger = logging.getLogger("engine.hello_world")
engine = Engine(
uuid="CHANGE-ME-PLEASE",
alias="Hello World Sample",
description="Demonstrates basic app structure and functionality.",
categories=["general"],
)
@engine.action(
display_name="Hello World",
description="Prints a greeting multiple times in the Task execution log.",
)
@engine.parameter_group(
name="general_parameters",
display_name="General Parameters",
description="Parameters for Hello World",
parameter_group=ParameterGroup(
Parameter(
type=Int(),
name="repeat",
display_name="Repeat",
description="Specify how many times to print.",
default=1,
required=True,
),
Parameter(
type=String(),
name="name",
display_name="Name",
description="Specify a name to print instead of World.",
required=False,
),
),
)
def hello_world(parameters):
i = 0
x = f"Hello {parameters.get('name') or 'World'}"
while i < parameters["repeat"]:
logger.info(x)
i += 1
return i, x
In the example above, there is just a single parameter group with only two parameters. However, an app might have 20 or 30 parameters spread across 5 to 10 parameter groups. In a situation like that, separating the parameter group code is definitely desirable to increase the readability and maintenance ease for the app. Moving parameter group definitions to separate files also makes it much easier to reuse them in several different apps.
Update pkg/executable.py
Below is an example of what the same code above will look like after the single General Parameters parameter group is split into two parameter groups and definition for each is replaced by a variables that will be defined in a separate file called models.py. The variables are then imported using a line that begins with from followed by the file name without extension preceded by a period. Lines added or changed are highlighted.
import logging
from nomnomdata.engine import Engine
from .models import name_parameters, repeat_parameters
logger = logging.getLogger("engine.hello_world")
engine = Engine(
uuid="CHANGE-ME-PLEASE",
alias="Hello World Sample",
description="Demonstrates basic app structure and functionality.",
categories=["general"],
)
@engine.action(
display_name="Hello World",
description="Prints a greeting multiple times in the Task execution log.",
)
@engine.parameter_group(name_parameters)
@engine.parameter_group(repeat_parameters)
def hello_world(parameters):
i = 0
x = f"Hello {parameters.get('name') or 'World'}"
while i < parameters["repeat"]:
logger.info(x)
i += 1
return i, x
It is important to note that the order in which the parameter groups are listed in the code above is significant. The name_parameters group is listed before the repeat_parameters group, which will cause it to be rendered after the repeat_parameters group in the Task user interface. Parameter groups are rendered in the opposite order of how they are listed in the code.
Create models.py
You can create as many separate files for parameter groups that you want and can name each file however you like. In this example, we will create a single file called models.py with each parameter individually defined and referenced in a defined parameter group. Below is the content of the file.
from nomnomdata.engine import Parameter, ParameterGroup
from nomnomdata.engine.parameters import Int, String
repeat_param = Parameter(
type=Int(),
name="repeat",
display_name="Repeat",
description="Specify how many times to print.",
default=1,
required=True,
)
name_param = Parameter(
type=String(),
name="name",
display_name="Name",
description="Specify a name to print instead of World.",
required=False,
)
repeat_parameters = ParameterGroup(
repeat_param,
name="repeat_parameters",
display_name="Repeat Parameters",
description="Parameters for Repeating",
)
name_parameters = ParameterGroup(
name_param,
name="name_parameters",
display_name="Name Parameters",
description="Parameters for Name Replacement",
)
Though this example doesn't demonstrate it, multiple parameters can be included within each parameter group definition and they can be defined inline rather than separately. Refer to the original pkg/executable.py content for an example of that.