Parameters¶
Flows can be parameterized so that the same logic can be executed multiple times with different inputs.
Tip
It may be helpful to read Technical Details: Execution to get a better understanding of why execution guards and multiple entrypoints are useful.
Passing Values¶
There are two parts involved in parameterizing a Flow
.
Keyword arguments passed to
Flow.__call__
are written to the flow’sDatastore
.A special layer
Parameters
is automatically registered to everyFlow
and is able to reference anyFlow
parameter with the same behavior as any otherLayer
.
# main.py
from laminar import Flow, Layer, Parameters
class ParameterFlow(Flow): ...
@ParameterFlow.register
class A(Layer):
def __call__(self, parameters: Parameters) -> None:
print(parameters.foo)
if flow := ParameterFlow():
flow(foo="bar")
python main.py
>>> "bar"
Parameters
can be used as a parameter like any other Layer
in a Flow
. It will automatically reference artifacts in the flow’s Datastore
and return the corresponding values. In this way, any arbitrary parameter can be passed into the Flow
.
Execution Guard¶
Because Flow.__call__
may take in values as parameters, additional care must be taken to avoid inefficiently calling Flow.__call__
.
Consider the following example:
import pandas as pd
...
flow(foo=pd.read_csv("path/to/large.csv"))
Here we are reading a large CSV into a pandas DataFrame and passing that in as a parameter to the flow. There are two issues:
We do not want to read the CSV every time we enter
main.py
.The CSV we need to read may not be present in the image the container is started in.
Instead we can guard against the CSV read with:
import pandas as pd
...
if flow := ParameterFlow():
flow(foo=pd.read_csv("path/to/large.csv"))
Flow.__bool__
will guard against Flow.__call__
being called again and also pd.read_csv
. Instead Flow.__bool__
will intelligently execute the Layer
that has been scheduled to run. By only reading data before the Flow
starts, we can only make our entire Flow
more efficient.
Tip
In general, we always recommend guarding Flow.__call__
in this way.