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 bymin_value
ormax_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 bymin_value
ormax_value
.
JSONParameter
: A JSON object map (i.e. dictionary). Strings are deserialized into JSON.
StringParameter
: A string, optionally bound bymax_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.
Once a parameter is promoted, it cannot be modified from the cube using cube.modify_parameter()
. Attempts to do so will raise an error.
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
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 |
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.
The default parameter value must be one the choices. Otherwise, the WorkFloe will fail validation.
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 PrinterCube, AnalyzerCube
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.