Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New container decorator #1068

Merged
merged 10 commits into from
Jun 12, 2024
71 changes: 71 additions & 0 deletions docs/examples/workflows/experimental/new_container_decorator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# New Container Decorator






=== "Hera"

```python linenums="1"
from typing_extensions import Annotated

from hera.shared import global_config
from hera.workflows import Input, Output, Parameter, WorkflowTemplate

global_config.experimental_features["decorator_syntax"] = True


# We start by defining our Workflow Template
w = WorkflowTemplate(name="my-template")


# This defines the template's inputs
class MyInput(Input):
user: str = "Hera"


class MyOutput(Output):
container_greeting: Annotated[
str,
Parameter(
name="container-greeting",
value_from={"path": "/tmp/hello_world.txt"},
),
]


@w.set_entrypoint
@w.container(command=["sh", "-c"], args=["echo Hello {{inputs.parameters.user}} | tee /tmp/hello_world.txt"])
def basic_hello_world(my_input: MyInput) -> MyOutput: ...
```

=== "YAML"

```yaml linenums="1"
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: my-template
spec:
entrypoint: basic-hello-world
templates:
- container:
args:
- echo Hello {{inputs.parameters.user}} | tee /tmp/hello_world.txt
command:
- sh
- -c
image: python:3.8
inputs:
parameters:
- default: Hera
name: user
name: basic-hello-world
outputs:
parameters:
- name: container-greeting
valueFrom:
path: /tmp/hello_world.txt
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# New Decorators Auto Template Refs






=== "Hera"

```python linenums="1"
from pydantic import BaseModel
from typing_extensions import Annotated

from hera.shared import global_config
from hera.workflows import ClusterWorkflowTemplate, Input, Output, Parameter, Workflow, WorkflowTemplate

global_config.experimental_features["decorator_syntax"] = True

wt = WorkflowTemplate(name="my-workflow-template")
cwt = ClusterWorkflowTemplate(name="my-cluster-workflow-template")

w = Workflow(generate_name="my-workflow-")


class SetupConfig(BaseModel):
a_param: str


class SetupOutput(Output):
environment_parameter: str
an_annotated_parameter: Annotated[int, Parameter(name="dummy-param")] # use an annotated non-str
setup_config: Annotated[SetupConfig, Parameter(name="setup-config")] # use a pydantic BaseModel


@cwt.script()
def setup() -> SetupOutput:
return SetupOutput(
environment_parameter="linux",
an_annotated_parameter=42,
setup_config=SetupConfig(a_param="test"),
result="Setting things up",
)


class ConcatConfig(BaseModel):
reverse: bool


class ConcatInput(Input):
word_a: Annotated[str, Parameter(name="word_a", default="")]
word_b: str
concat_config: ConcatConfig = ConcatConfig(reverse=False)


@wt.script()
def concat(concat_input: ConcatInput) -> Output:
res = f"{concat_input.word_a} {concat_input.word_b}"
if concat_input.reverse:
res = res[::-1]
return Output(result=res)


class WorkerConfig(BaseModel):
param_1: str
param_2: str


class WorkerInput(Input):
value_a: str = "my default"
value_b: str
an_int_value: int = 42
a_basemodel: WorkerConfig = WorkerConfig(param_1="Hello", param_2="world")


class WorkerOutput(Output):
value: str


@w.set_entrypoint
@w.dag()
def worker(worker_input: WorkerInput) -> WorkerOutput:
setup_task = setup()
task_a = concat(
ConcatInput(
word_a=worker_input.value_a,
word_b=setup_task.environment_parameter + str(setup_task.an_annotated_parameter),
)
)
task_b = concat(ConcatInput(word_a=worker_input.value_b, word_b=setup_task.result))
final_task = concat(ConcatInput(word_a=task_a.result, word_b=task_b.result))

return WorkerOutput(value=final_task.result)
```

=== "YAML"

```yaml linenums="1"
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: my-workflow-
spec:
entrypoint: worker
templates:
- dag:
tasks:
- name: setup_task
templateRef:
clusterScope: true
name: my-cluster-workflow-template
template: setup
- arguments:
parameters:
- name: word_a
value: '{{inputs.parameters.value_a}}'
- name: word_b
value: '{{tasks.setup_task.outputs.parameters.environment_parameter}}{{tasks.setup_task.outputs.parameters.dummy-param}}'
- name: concat_config
value: '{"reverse": false}'
depends: setup_task
name: task_a
templateRef:
name: my-workflow-template
template: concat
- arguments:
parameters:
- name: word_a
value: '{{inputs.parameters.value_b}}'
- name: word_b
value: '{{tasks.setup_task.outputs.result}}'
- name: concat_config
value: '{"reverse": false}'
depends: setup_task
name: task_b
templateRef:
name: my-workflow-template
template: concat
- arguments:
parameters:
- name: word_a
value: '{{tasks.task_a.outputs.result}}'
- name: word_b
value: '{{tasks.task_b.outputs.result}}'
- name: concat_config
value: '{"reverse": false}'
depends: task_a && task_b
name: final_task
templateRef:
name: my-workflow-template
template: concat
inputs:
parameters:
- default: my default
name: value_a
- name: value_b
- default: '42'
name: an_int_value
- default: '{"param_1": "Hello", "param_2": "world"}'
name: a_basemodel
name: worker
outputs:
parameters:
- name: value
valueFrom:
parameter: '{{tasks.final_task.outputs.result}}'
```

24 changes: 24 additions & 0 deletions examples/workflows/experimental/new-container-decorator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: my-template
spec:
entrypoint: basic-hello-world
templates:
- container:
args:
- echo Hello {{inputs.parameters.user}} | tee /tmp/hello_world.txt
command:
- sh
- -c
image: python:3.8
inputs:
parameters:
- default: Hera
name: user
name: basic-hello-world
outputs:
parameters:
- name: container-greeting
valueFrom:
path: /tmp/hello_world.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: my-workflow-
spec:
entrypoint: worker
templates:
- dag:
tasks:
- name: setup_task
templateRef:
clusterScope: true
name: my-cluster-workflow-template
template: setup
- arguments:
parameters:
- name: word_a
value: '{{inputs.parameters.value_a}}'
- name: word_b
value: '{{tasks.setup_task.outputs.parameters.environment_parameter}}{{tasks.setup_task.outputs.parameters.dummy-param}}'
- name: concat_config
value: '{"reverse": false}'
depends: setup_task
name: task_a
templateRef:
name: my-workflow-template
template: concat
- arguments:
parameters:
- name: word_a
value: '{{inputs.parameters.value_b}}'
- name: word_b
value: '{{tasks.setup_task.outputs.result}}'
- name: concat_config
value: '{"reverse": false}'
depends: setup_task
name: task_b
templateRef:
name: my-workflow-template
template: concat
- arguments:
parameters:
- name: word_a
value: '{{tasks.task_a.outputs.result}}'
- name: word_b
value: '{{tasks.task_b.outputs.result}}'
- name: concat_config
value: '{"reverse": false}'
depends: task_a && task_b
name: final_task
templateRef:
name: my-workflow-template
template: concat
inputs:
parameters:
- default: my default
name: value_a
- name: value_b
- default: '42'
name: an_int_value
- default: '{"param_1": "Hello", "param_2": "world"}'
name: a_basemodel
name: worker
outputs:
parameters:
- name: value
valueFrom:
parameter: '{{tasks.final_task.outputs.result}}'
30 changes: 30 additions & 0 deletions examples/workflows/experimental/new_container_decorator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing_extensions import Annotated

from hera.shared import global_config
from hera.workflows import Input, Output, Parameter, WorkflowTemplate

global_config.experimental_features["decorator_syntax"] = True


# We start by defining our Workflow Template
w = WorkflowTemplate(name="my-template")


# This defines the template's inputs
class MyInput(Input):
user: str = "Hera"


class MyOutput(Output):
container_greeting: Annotated[
str,
Parameter(
name="container-greeting",
value_from={"path": "/tmp/hello_world.txt"},
),
]


@w.set_entrypoint
@w.container(command=["sh", "-c"], args=["echo Hello {{inputs.parameters.user}} | tee /tmp/hello_world.txt"])
def basic_hello_world(my_input: MyInput) -> MyOutput: ...
Loading
Loading