Is your feature request related to a problem? Please describe.
#1387
Plugin templates aren't directly supported by Hera; you have to use the model classes. It should be possible to use the plugins from the plugin directory using Hera's custom classes. Couple of examples:
Hello world
from hera.workflows import Workflow
from hera.workflows.models import Template, Plugin
class MyPlugin(Plugin):
hello: dict = {}
w = Workflow(
generate_name="hello-example-",
entrypoint="main",
)
# unfortunately need to append as context manager doesn't
# work for model classes:
w.templates.append(
Template(
name="main",
plugin=MyPlugin(
hello={},
),
)
)
For YAML:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-example-
spec:
entrypoint: main
templates:
- name: main
plugin:
hello: {}
Slack plugin
from hera.workflows import Workflow
from hera.workflows.models import Template, Plugin
from pydantic.v1 import BaseModel
class Slack(BaseModel):
text: str
class SlackPlugin(Plugin):
slack: Slack
w = Workflow(
generate_name="slack-example-",
entrypoint="main",
)
w.templates.append(
Template(
name="main",
plugin=SlackPlugin(
slack=Slack(
text="{{workflow.name}} finished!",
),
),
)
)
For YAML:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: slack-example-
spec:
entrypoint: main
templates:
- name: main
plugin:
slack:
text: '{{workflow.name}} finished!'
Describe the solution you'd like
These examples should be possible using a new PluginTemplate class which has the same behaviour under Workflow and DAG context managers as Scripts/Containers/etc.
Having the examples above in the repo is not currently possible as they fail testing due to the roundtrip test (assert workflow == HeraWorkflow.from_dict(workflow.to_dict())) not understanding how to interpret the value under plugin (i.e. it drops it). LHS vs RHS:
...
+ plugin=SlackPlugin(slack=Slack(text='{{workflow.name}} finished!')),
...
- plugin=Plugin(),
E.g. hello world would become:
from hera.workflows import PluginTemplate, Workflow
from hera.workflows.models import Template, Plugin
class HelloWorldPlugin(Plugin):
hello: dict
with Workflow(
generate_name="hello-example-",
entrypoint="main",
) as w:
PluginTemplate(
name="main",
plugin=HelloWorldPlugin(
hello={},
),
)
Using a DAG to show the callable behaviour:
from hera.workflows import DAG, PluginTemplate, Workflow
from hera.workflows.models import Plugin
class HelloWorldPlugin(Plugin):
hello: dict
with Workflow(
generate_name="hello-example-",
entrypoint="main",
) as w:
hello_template = PluginTemplate(
name="hello",
plugin=HelloWorldPlugin(
hello={},
),
)
with DAG(name="main") as d:
hello_template(name="hello-1")
hello_template(name="hello-2")
Describe alternatives you've considered
Use the model classes, not much better than YAML 🙂
Additional context
Slack thread https://cloud-native.slack.com/archives/C03NRMD9KPY/p1747674689849999
Is your feature request related to a problem? Please describe.
#1387
Plugin templates aren't directly supported by Hera; you have to use the model classes. It should be possible to use the plugins from the plugin directory using Hera's custom classes. Couple of examples:
Hello world
For YAML:
Slack plugin
For YAML:
Describe the solution you'd like
These examples should be possible using a new
PluginTemplateclass which has the same behaviour under Workflow and DAG context managers as Scripts/Containers/etc.Having the examples above in the repo is not currently possible as they fail testing due to the roundtrip test (
assert workflow == HeraWorkflow.from_dict(workflow.to_dict())) not understanding how to interpret the value underplugin(i.e. it drops it). LHS vs RHS:E.g. hello world would become:
Using a DAG to show the callable behaviour:
Describe alternatives you've considered
Use the model classes, not much better than YAML 🙂
Additional context
Slack thread https://cloud-native.slack.com/archives/C03NRMD9KPY/p1747674689849999