Parameters

Floe is designed to encourage reuse of WorkFloes and cubes. To facilitate this, Parameters can be added to both cubes and WorkFloes. Floe comes with built-in parameter classes for several different types of parameter. Just like WorkFloes and cubes, Parameters are represented internally using the Floe specification.

Parameter Types

There are seven fundamental parameter types in Floe:

  • BooleanParameter: True or False. The strings ‘1’ or ‘true’ are coerced to True, everything else is False.

  • DecimalParameter: A floating point value optionally bounded by min_value or max_value.

  • FileInputParameter: A string containing the name of a file to be used for input.

  • FileOutputParameter: A string containing the name of a file to be used for output.

  • IntegerParameter: An integer optionally bounded by min_value or max_value.

  • JSONParameter: A JSON object map (i.e. dictionary). Strings are deserialized into JSON.

  • StringParameter: A string, optionally bound by max_length.

Adding a cube parameter

Cube Parameters can be added by instantiating the parameter on the class:

# param_example_cubes.py
from floe.api import ComputeCube, IntegerParameter

class ExampleCube(ComputeCube):

    # Below is an example parameter that demonstrates some of the available features
    example_int = IntegerParameter(
        title="Example Integer",
        default=1,
        description="Provide a human-readable message here that describes the parameter",
        min_value=0,
        max_value=100,
    )

Specifying Parameters at run time

When a WorkFloe is executed as a script, Floe will collect all Parameters for all cubes and build an argument parser which recognizes those Parameters, where each cube parameter is prefixed by the name of the cube it belongs to.

In the example WorkFloe below, the FileInputCube and FileOutputCube both take Parameters that specify the filenames to read from and write to:

# example_floe.py
from my_cubes import PrinterCube, FileInputCube, FileOutputCube
from floe.api import WorkFloe

job = WorkFloe("Print Data Floe")
ifs = FileInputCube()
printer = PrinterCube()
ofs = FileOutputCube()

job.add_cubes(ifs, printer, ofs)

ifs.success.connect(printer.intake)
printer.success.connect(ofs.intake)

if __name__ == "__main__":
    job.run()

To display help:

$ python example_floe.py --help

To specify the data_in parameter for the ifs cube:

$ python example_floe.py --ifs-data_in mymolecules.oeb

Getting a Parameter value

When a WorkFloe is started, but before each cube’s begin() method is called, all parameter values are parsed and then made available to each cube as a Namespace stored as self.args. To get a Parameter’s value, reference the parameter’s name (not a promoted name) in the namespace as shown in the example below.

Example:

class ExampleCube(ComputeCube):

    example_param = StringParameter()

    def process(self, data, port):
        print("Parameter value is", self.args.example_param)

Grouping cube parameters

Parameters can be associated into logical groups as a hint to a user interface.

Example:

class ExampleCube(ComputeCube):

    repetition_string = StringParameter()
    repetition_times = IntegerParameter()
    repetition_group = ParameterGroup(
        "Example Parameter Group",
        parameters=[
            repetition_string,
            repetition_times,
        ],
        description="These parameters are associated with the repetition operation of this cube",
        order=3,
        collapsed=True,
    )


    def process(self, data, port):
        print(self.args.repetition_string * self.args.repetition_times)

Promoting a cube parameter

By default, cube Parameters are namespaced with a prefix, that is the name of the cube the parameter belongs to. For example, if a cube named testcube had a parameter named limit, the full parameter name for the command line interface would be --testcube-limit. A parameter can be promoted to allow for a more terse name that no longer includes the parent cube. Additionally, promoted Parameters can assume a different promoted name.

When promoting multiple cubes parameters to the same name, each default and order attribute must also have the same value. Otherwise, the WorkFloe will fail validation. The default and order attributes can be modified by calling the modify_parameter method on a cube parameter.

Example:

# example_floe.py
from my_cubes import AnalyzerCube, PrinterCube
from floe.api import WorkFloe, FileInputCube, FileOutputCube, FileInputParameter, IntegerParameter

job = WorkFloe("Workfloe Parameter floe")
ifs = FileInputCube()

# Promote the 'data_in' parameter, with a different promoted name
ifs.modify_parameter(ifs.data_in, promoted=True, promoted_name="infile")

analyzer = AnalyzerCube()
printer = PrinterCube()

# Promote analyzer and printer cubes parameters to common name and set the 'default' attribute
analyzer.modify_parameter(analyzer.size, promoted=True, promoted_name="n_clusters", default=10)
printer.modify_parameter(printer.size, promoted=True, promoted_name="n_clusters", default=10)

ofs = FileOutputCube()

job.add_cubes(ifs, analyzer, printer, ofs)

ifs.success.connect(analyzer.intake)
analyzer.success.connect(printer.intake)
printer.success.connect(ofs.intake)

if __name__ == "__main__":
    job.run()

Note

Serializing a Floe into JSON will preserve promoted Parameters

Grouping promoted parameters

Promoted parameters can be associated into logical groups as a hint to the Orion user interface.

Parameters that have been promoted to the same name cannot be in different promoted parameter groups. Otherwise, the WorkFloe will fail validation. Promoted parameter group membership can be modified by calling the modify_parameter_group method of a floe.

The collapsed attribute of a group controls the initial state when displaying in the UI. By default, groups are expanded (collapsed=False). The collapsed attribute can be modified with the modify_parameter_group() method.

Example:

# example_floe.py
from my_cubes import AnalyzerCube, PrinterCube
from floe.api import WorkFloe, FileInputCube, FileOutputCube

job = WorkFloe("Workfloe Parameter floe")
ifs = FileInputCube()

# Promote the 'data_in' parameter
ifs.modify_parameter(ifs.data_in, promoted=True, promoted_name="infile")

analyzer = AnalyzerCube()
printer = PrinterCube()

# Group promoted parameters
# Both analyzer.size and printer.size will be automatically promoted (since they are not promoted already)
job.create_parameter_group(
    "example_group",
    title="Example Promoted Parameter Group",
    parameters=[
        analyzer.size,
        printer.size,
        "infile",
        # ^ If a parameter is already promoted, the promoted name may be passed instead of the parameter itself
        # All parameters promoted to the name 'infile' will be added to the group
    ],
    description="These parameters are associated with the size of multiple cubes and the input file",
    order=1,
    collapsed=True,
)

ofs = FileOutputCube()

job.add_cubes(ifs, analyzer, printer, ofs)

ifs.success.connect(analyzer.intake)
analyzer.success.connect(printer.intake)
printer.success.connect(ofs.intake)

if __name__ == "__main__":
    job.run()

By default, the Orion UI creates Input/Output groups containing promoted parameters that meet the criteria of an input/output parameter. Any promoted parameter that meets the criteria of an input/output parameter, but has been explicitly put in another group, will remain in the group it was explicitly put. The Input/Output groups may be overridden by the Floe author by defining promoted parameter groups named “input_group” and “output_group” respectively.

Parameter Attributes

Parameter Attributes

Name

Type

Override

Description

name

string

no

The name of the parameter as referenced by a cube

required

bool

no

Whether or not the parameter’s value must be set

default

param

yes

The default value of the parameter

description

string

yes

Explanatory text in a user interface

help_text

string

yes

Alias for description

hidden

bool

yes

Whether or not to show in a user interface

level

string

yes

Indicates class of user expected to modify the parameter

choices

list

yes

A list of valid values

many

bool

yes

Indicates the parameter value is a list of its type

max_length

int, None

yes

The max length of a string; None implies no limit

max_value

int, None

yes

The max value of an integer; None implies no upper limit

min_value

int, None

yes

The min value of the integer; None implies no lower limit

null

bool

yes

Indicates that the value of the parameter may be None

promoted_name

string, None

yes

Name of the parameter to hold when promoted

promoted

bool

yes

Whether a parameter is to be elevated from a cube-level to WorkFloe

static

bool

yes

Indicates that the value of the parameter is static

title

string, None

yes

The title of the parameter to use in a user interface

order

int, None

yes

The display order of the parameter in a user interface

Storing multiple values

If desired, there is also the option to store multiple values in a parameter, rather than one singular value. This is accomplished by setting the parameter’s attribute many equal to True, making the parameter function as a list. This is highlighted in the following examples:

class SampleCube(Compute Cube):

    ExampleStringParam = StringParameter(
        title="TestParameter",
        many=True,
        description="This is a sample parameter where the argument 'many' is set to True",
        default = ["This", "functions", "as", "a", "list"],
    )

    ExampleDecimalParam = DecimalParameter(
        title = "TestParameter2",
        many = True,
        description = "This is another sample parameter with 'many=True'",
        default = [12.4, 0.7, 9.43, 6.44444],
    )

To input the desired values on the command line, write out the inputs separated by spaces following the parameter name:

$ --SampleCube-ExampleStringParam This functions as a list
$ --SampleCube-ExampleDecimalParam 12.4 0.7 9.43 6.44444

Specifying parameter choices

A parameter can be defined with a set of valid choices. By default, only one choice can be selected for the parameter’s value.

class ExampleCube(ComputeCube):

    example_param = StringParameter(
         choices=["Foo", "bar", "Fizz"],
         default="Foo",
     )

    def process(self, data, port):
        print("Parameter value is", self.args.example_param)

When defining the default on a parameter with choices, the value must be within choices. None is also valid when required is set to True.

Providing a static value for a parameter

Sometimes, it is useful to fix a value of a parameter for a specific use of a cube. This can be achieved simply, as demonstrated in the following example:

# example.py
from param_example_cubes import ExampleCube

# Instantiate the cube
example = ExampleCube()

# Fix the value of the 'example_int' parameter on the example cube
example.set_parameters(example_int=42)

Note

Serializing a Floe into JSON will preserve static Parameters, so long as the value of the parameter can be serialized as well.

Ordering cube parameters for user interface display

The order attribute defines the sequence in which parameters will be displayed in the Orion UI. By default, the UI will set parameter order equal to the rank of the cube that defines this parameter. The order can be modified with the modify_parameter() function. The value of the order attribute is a positive integer from 0 to 999, where parameters with lower order will be displayed first in the user interface. Order ties will be broken by sorting parameters alphabetically by name.

Example:

# example_floe.py
from my_cubes import PrinterCube, FileInputCube, FileOutputCube
from floe.api import WorkFloe, FileInputParameter

job = WorkFloe("Workfloe Parameter floe")
ifs = FileInputCube()

# Promote the 'data_in' parameter, and change its default order
ifs.modify_parameter(ifs.data_in, promoted=True, promoted_name="infile", order=3)

printer = PrinterCube()

# Change the order of 'limit' parameter, but do not promote it
ifs.modify_parameter(printer.limit, order=1)

ofs = FileOutputCube()

job.add_cubes(ifs, printer, ofs)

ifs.success.connect(analyzer.intake)
analyzer.success.connect(printer.intake)
printer.success.connect(ofs.intake)

if __name__ == "__main__":
    job.run()

When a Cube parameter has an order attribute set by the Cube author, promoting this parameter in a Floe will set its order to rank of the cube in the Floe, unless the order is explicitly modified by Floe author.

For local development invoking WorkFloe floe run my_workfloe_name.py --help will print the parameters grouped and ordered as in Orion UI:

  • Input (based on parameter type)

  • Output (based on parameter type)

  • Promoted + Required (includes only promoted or required parameters without default)

Within each group, parameters are ordered by order attribute, then by cube rank, then parameter title.

Ordering parameter groups for user interface display

The order attribute of a parameter group defines the sequence in which groups will be displayed in the Orion UI. By default, the order of a group is None, which means it will be displayed after all other parameters, and after other groups with a specified order. The order can be modified with the modify_parameter_group() function. The value of the order attribute, when not the default of None, is a positive integer from 0 to 999, where groups with lower order will be displayed first in the user interface. Within the group, parameters will be displayed according to the parameter ordering rules. Order ties between groups will be broken by sorting groups alphabetically by name. Order ties between a group and an ungrouped parameter will be won by the ungrouped parameter.

Example:

# example_floe.py
from my_cubes import AnalyzerCube, PrinterCube
from floe.api import WorkFloe, FileInputCube, FileOutputCube

job = WorkFloe("Workfloe Parameter floe")
ifs = FileInputCube()

analyzer = AnalyzerCube()
printer = PrinterCube()

# Promote 'data_in'
ifs.modify_parameter(ifs.data_in, promoted=True, promoted_name="infile")

job.create_parameter_group(
    "example_group",
    title="Example Promoted Parameter Group",
    parameters=[
        analyzer.size,
        printer.size,
        "infile",
    ],
    parameter_orders=[2, 2, 1],
    # ^ Convenience for setting parameter ordering within the group
    # infile will be displayed first
    description="These parameters are associated with the size of multiple cubes and the input file",
    order=1,
    collapsed=True,
)
# The group will be displayed after 'data_out' on the UI

ofs = FileOutputCube()

# Promote 'data_out' and set an order
ofs.modify_parameter(ofs.data_out, promoted=True, promoted_name="outfile", order=0)

job.add_cubes(ifs, analyzer, printer, ofs)

ifs.success.connect(analyzer.intake)
analyzer.success.connect(printer.intake)
printer.success.connect(ofs.intake)

if __name__ == "__main__":
    job.run()

The default input and output groups will always be displayed first regardless of the order of other groups/promoted parameters. If the default input/output group(s) are overridden, they will assume normal group ordering, and will not necessarily be displayed first.

Basic vs. Advanced Parameters

Parameters can be marked as ‘basic’ or ‘advanced’ using the level argument, as shown in the example below. All Parameters are ‘basic’ by default. There are no side effects to setting level, it is only present as an aid to user interfaces.

# param_example_cubes.py
from floe.api import ComputeCube, IntegerParameter

class ExampleCube(ComputeCube):

    # Below is an example parameter that demonstrates some of the available features
    example_int = IntegerParameter(
        default=1,
        description="Provide a human-readable message here that describes the parameter",
        min_value=0,
        max_value=100,
        level="basic"
    )

Overriding parameter fields on a cube

Any attribute for a cube parameter may be modified using the modify_parameter() function.

from floe.api import ComputeCube, IntegerParameter

class ExampleCube(ComputeCube):

    # Below is an example parameter that demonstrates some of the available features
    example_int = IntegerParameter(
        default=1,
        description="Provide a human-readable message here that describes the parameter",
        min_value=0,
        max_value=100,
        level="basic"
    )

cube = ExampleCube()
cube.modify_parameter(
    cube.example_int,
    default=10,
    promoted=True,
    promoted_name="count"
)

Overriding defaults in a derived class

Each parameter has several attributes that can be overridden on a cube by modifying parameter_overrides.

Note

The parameter_overrides class attribute should never be modified aside from its initial definition in a class. Because it is a class attribute, any modifications to parameter_overrides will modify its value for every use of that class.

class ExampleParamOverrideCube(ExampleCube):

    parameter_overrides = {
        "example_int": {
            "default": 2,
            "hidden": True,
        },
    }

Parameter Methods

If a custom parameter is needed, then subclass one of the fundamental types and override one or more methods.

Parameter.get_runtime_value(value)

The get_runtime_value(value) method is used to transform a parameter’s value into a (possibly different) value required by a cube. Parameter validation is performed before this method is called.