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

Script annotations for input Parameters #708

Merged
merged 5 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion docs/examples/workflows/callable_script.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
```python linenums="1"
from typing import List

try:
from typing import Annotated # type: ignore
except ImportError:
from typing_extensions import Annotated # type: ignore

from pydantic import BaseModel

from hera.shared import global_config
from hera.workflows import Script, Steps, Workflow, script
from hera.workflows import Parameter, Script, Steps, Workflow, script

# Note, setting constructor to runner is only possible if the source code is available
# along with dependencies include hera in the image.
Expand All @@ -25,6 +30,7 @@
# Runner script constructor is still and experimental feature and we need to explicitly opt in to it
# Note that experimental features are subject to breaking changes in future releases of the same major version
global_config.experimental_features["script_runner"] = True
global_config.experimental_features["script_annotations"] = True


# An optional pydantic input type
Expand Down Expand Up @@ -71,11 +77,28 @@
return Output(output=[Input.parse_raw(input)])


# Use the script_annotations feature to seamlessly enable aliased kebab-case names
# as your template interface, while using regular snake_case in the Python code
@script()
def function_kebab(
a_but_kebab: Annotated[int, Parameter(name="a-but-kebab")] = 2,
b_but_kebab: Annotated[str, Parameter(name="b-but-kebab")] = "foo",
) -> Output:
return Output(output=[Input(a=a_but_kebab, b=b_but_kebab)])


@script()
def function_kebab_object(input_values: Annotated[Input, Parameter(name="input-values")]) -> Output:
return Output(output=[input_values])


with Workflow(name="my-workflow") as w:
with Steps(name="my-steps") as s:
my_function(arguments={"input": Input(a=2, b="bar")})
str_function(arguments={"input": Input(a=2, b="bar").json()})
another_function(arguments={"inputs": [Input(a=2, b="bar"), Input(a=2, b="bar")]})
function_kebab(arguments={"a-but-kebab": 3, "b-but-kebab": "bar"})
function_kebab_object(arguments={"input-values": Input(a=3, b="bar")})
```

=== "YAML"
Expand Down Expand Up @@ -107,6 +130,20 @@
value: '[{"a": 2, "b": "bar"}, {"a": 2, "b": "bar"}]'
name: another-function
template: another-function
- - arguments:
parameters:
- name: a-but-kebab
value: '3'
- name: b-but-kebab
value: bar
name: function-kebab
template: function-kebab
- - arguments:
parameters:
- name: input-values
value: '{"a": 3, "b": "bar"}'
name: function-kebab-object
template: function-kebab-object
- inputs:
parameters:
- name: input
Expand All @@ -119,6 +156,9 @@
- examples.workflows.callable_script:my_function
command:
- python
env:
- name: script_annotations
value: ''
image: my-image-with-python-source-code-and-dependencies
source: '{{inputs.parameters}}'
- inputs:
Expand All @@ -133,6 +173,9 @@
- examples.workflows.callable_script:str_function
command:
- python
env:
- name: script_annotations
value: ''
image: my-image-with-python-source-code-and-dependencies
source: '{{inputs.parameters}}'
- inputs:
Expand All @@ -147,6 +190,46 @@
- examples.workflows.callable_script:another_function
command:
- python
env:
- name: script_annotations
value: ''
image: my-image-with-python-source-code-and-dependencies
source: '{{inputs.parameters}}'
- inputs:
parameters:
- default: '2'
name: a-but-kebab
- default: foo
name: b-but-kebab
name: function-kebab
script:
args:
- -m
- hera.workflows.runner
- -e
- examples.workflows.callable_script:function_kebab
command:
- python
env:
- name: script_annotations
value: ''
image: my-image-with-python-source-code-and-dependencies
source: '{{inputs.parameters}}'
- inputs:
parameters:
- name: input-values
name: function-kebab-object
script:
args:
- -m
- hera.workflows.runner
- -e
- examples.workflows.callable_script:function_kebab_object
command:
- python
env:
- name: script_annotations
value: ''
image: my-image-with-python-source-code-and-dependencies
source: '{{inputs.parameters}}'
```
Expand Down
80 changes: 80 additions & 0 deletions docs/examples/workflows/script_annotations_alias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Script Annotations Alias






=== "Hera"

```python linenums="1"
try:
from typing import Annotated # type: ignore
except ImportError:
from typing_extensions import Annotated # type: ignore

from hera.shared import global_config
from hera.workflows import Workflow, script
from hera.workflows.parameter import Parameter
from hera.workflows.steps import Steps

global_config.experimental_features["script_annotations"] = True


@script()
def echo(
a_name: Annotated[str, Parameter(name="another_name")],
):
print(a_name)


with Workflow(generate_name="test-types-", entrypoint="my_steps") as w:
with Steps(name="my_steps") as s:
echo(arguments={"a_name": "hello there"})
```

=== "YAML"

```yaml linenums="1"
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: test-types-
spec:
entrypoint: my_steps
templates:
- name: my_steps
steps:
- - arguments:
parameters:
- name: a_name
value: hello there
name: echo
template: echo
- inputs:
parameters:
- name: another_name
name: echo
script:
command:
- python
env:
- name: script_annotations
value: ''
image: python:3.8
source: 'import os

import sys

sys.path.append(os.getcwd())

import json

try: another_name = json.loads(r''''''{{inputs.parameters.another_name}}'''''')

except: another_name = r''''''{{inputs.parameters.another_name}}''''''


print(a_name)'
```

119 changes: 119 additions & 0 deletions docs/examples/workflows/script_annotations_combined_new.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Script Annotations Combined New






=== "Hera"

```python linenums="1"
try:
from typing import Annotated # type: ignore
except ImportError:
from typing_extensions import Annotated # type: ignore

from hera.shared import global_config
from hera.workflows import Workflow, script
from hera.workflows.parameter import Parameter
from hera.workflows.steps import Steps

global_config.experimental_features["script_annotations"] = True


@script()
def echo_all(
an_int: Annotated[int, Parameter(description="an_int parameter", default=1, enum=[1, 2, 3])],
a_bool: Annotated[bool, Parameter(description="a_bool parameter", default=True, enum=[True, False])],
a_string: Annotated[str, Parameter(description="a_string parameter", default="a", enum=["a", "b", "c"])],
):
print(an_int)
print(a_bool)
print(a_string)


with Workflow(generate_name="test-types-", entrypoint="my_steps") as w:
with Steps(name="my_steps") as s:
echo_all(arguments={"an_int": 1, "a_bool": True, "a_string": "a"})
```

=== "YAML"

```yaml linenums="1"
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: test-types-
spec:
entrypoint: my_steps
templates:
- name: my_steps
steps:
- - arguments:
parameters:
- name: an_int
value: '1'
- name: a_bool
value: 'true'
- name: a_string
value: a
name: echo-all
template: echo-all
- inputs:
parameters:
- default: '1'
description: an_int parameter
enum:
- '1'
- '2'
- '3'
name: an_int
- default: 'true'
description: a_bool parameter
enum:
- 'True'
- 'False'
name: a_bool
- default: a
description: a_string parameter
enum:
- a
- b
- c
name: a_string
name: echo-all
script:
command:
- python
env:
- name: script_annotations
value: ''
image: python:3.8
source: 'import os

import sys

sys.path.append(os.getcwd())

import json

try: a_bool = json.loads(r''''''{{inputs.parameters.a_bool}}'''''')

except: a_bool = r''''''{{inputs.parameters.a_bool}}''''''

try: a_string = json.loads(r''''''{{inputs.parameters.a_string}}'''''')

except: a_string = r''''''{{inputs.parameters.a_string}}''''''

try: an_int = json.loads(r''''''{{inputs.parameters.an_int}}'''''')

except: an_int = r''''''{{inputs.parameters.an_int}}''''''


print(an_int)

print(a_bool)

print(a_string)'
```

Loading