h1flow.h1step

Module Contents

Classes

Node

Base class for h1st Node

Action

@TODO: use .add(yes = (Model2(), "model2")) instead ?

NoOp

A do-nothing action.

Decision

H1st conditional node

class h1flow.h1step.Node(containable: h1st.h1flow.h1step_containable.NodeContainable = None, id: str = None)

Base class for h1st Node

property id(self) str
property edges(self) List[Tuple[Node, str]]
Returns

list of tuple(next_node, edge_label) which next_node is connected from this node edge_label = ‘yes’/’no’ in case of condition nodes edge_label = None in case of normal nodes

property graph(self) Graph
property transform_input(self) Callable
property transform_output(self) Callable
add(self, node: Union[Node, h1st.h1flow.h1step_containable.NodeContainable, None] = None, yes: Union[Node, h1st.h1flow.h1step_containable.NodeContainable, None] = None, no: Union[Node, h1st.h1flow.h1step_containable.NodeContainable, None] = None, id: str = None) Union[Node, List[Node]]

The bridge function to add nodes to a graph. This will invoke the Graph.add() function and will then connect this node to newly added nodes.

_execute(self, command: Optional[str], inputs: Dict[str, Any], state: Dict) Dict

The execution of graph will be executed recursively. The upstream node will invoke the down stream nodes to be executed. If it is the start node, this function will be invoked by the graph. The containable.call() will be invoked if this node contains a NodeContainable object. Otherwise, its call() function will be invoked.

Parameters
  • command – for this node to know which flow (predict, train, …) the graph is running

  • inputs – the input data to execute the node. During the graph execution, output of all executed nodes will be merged into inputs

  • state – executing state

call(self, command: Optional[str], inputs: Dict[str, Any]) Dict

Subclass may need to override this function to perform the execution depending the type of node. This function is invoked by the framework and user will never need to call it.

to_dot_node(self, visitor)

Subclass will need to implement this function to construct and return the graphviz compatible node

validate_output(self, input_data: Dict = None, schema=None, command='predict')

Invokes the call function the node with given input data, then verifies if output of the node conforming with the output schema of this node. Framework will look up the output schema for this node in the schemas object loaded by the graph from schemas.py using id of this node.

Parameters
  • inputs – input data to invoke the call function of the node

  • schema – provided schema to validate with output

  • command – the command param to invoke the call function of the node

_get_edge_data(self, edge, node_output)

Gets data from node’s output to pass to the next node

_validate_output(self, node_output) bool
class h1flow.h1step.Action(containable: h1st.h1flow.h1step_containable.NodeContainable = None, id: str = None)

Bases: Node

@TODO: use .add(yes = (Model2(), “model2”)) instead ?

H1st non-conditional node. It is used to add a NodeContainable instance with an ID to yes/no branch of a conditional node

Add nodes for yes/no branch of a conditional node
import h1st.core as h1

class MyGraph(h1.Graph)
    def __init__(self):
        yes, no = self.start()
            .add(h1.Decision(Model1()))
            .add(
                yes = h1.Action(Model2(), id="model2"), # with an id
                no = Model3()                           # without an id
            )

        yes.add(Model4())
        no.add(Model5())

        self.end()
to_dot_node(self, visitor)

Constructs and returns the graphviz compatible node

class h1flow.h1step.NoOp(containable: h1st.h1flow.h1step_containable.NodeContainable = None, id: str = None)

Bases: Action

A do-nothing action.

call(self, command, inputs)

Subclass may need to override this function to perform the execution depending the type of node. This function is invoked by the framework and user will never need to call it.

class h1flow.h1step.Decision(containable: h1st.h1flow.h1step_containable.NodeContainable = None, id: str = None, result_field='results', decision_field='prediction')

Bases: Action

H1st conditional node

Graph with conditional node
import h1st.core as h1

class MyGraph(h1.Graph)
    def __init__(self):
        yes, no = self.start()
            .add(h1.Decision(Model1()))
            .add(
                yes = Model2()
                no = Model3()
            )

        yes.add(Model4())
        no.add(Model5())

        self.end()
Graph with conditional node using custom result_field and decision_field
import h1st.core as h1

class Model1(h1.Model):
    def predict(data):
        return {
            'predictions': [
                {gx: 10, gy: 20, label: True},
                {gx: 11, gy: 21, label: True},
                {gx: 12, gy: 22, label: False},
            ]
        }

class MyGraph(h1.Graph)
    def __init__(self):
        yes, no = self.start()
            .add(h1.Decision(Model1(), result_field='predictions', decision_field='label'))
            .add(
                yes = Model2()
                no = Model3()
            )

        yes.add(Model4())
        no.add(Model5())

        self.end()
to_dot_node(self, visitor)

Constructs and returns the graphviz compatible node

_get_edge_data(self, edge, node_output)

splits data for yes/no path from the node’s output to pass to the next node

_validate_output(self, node_output) bool

This will ensure the result’s structure is valid for decision node.

node_output must be a dictionary containing ‘results’ key and each item will have a field whose name = ‘prediction’ with bool value to decide whether the item belongs to yes or no branch

{

‘results’: [{ ‘prediction’: True/False, …}], ‘other_key’: …,

}

or a dictionary containing only one key
{

‘your_key’: [{ ‘prediction’: True/False, …}]

}