Hello World
Let’s take a look at the Workflow from the Quick Start guide:
from hera.workflows import Steps, Workflow, WorkflowsService, script
@script()
def echo(message: str):
print(message)
with Workflow(
generate_name="hello-world-",
entrypoint="steps",
namespace="argo",
workflows_service=WorkflowsService(host="https://localhost:2746")
) as w:
with Steps(name="steps"):
echo(arguments={"message": "Hello world!"})
w.create()
Wait, What’s a Workflow?
If you’re new to Argo Workflows, it helps to first understand that it runs on Kubernetes. In Kubernetes, a Custom
Resource Definition (CRD) is how you define a new type of object. Argo Workflows adds its own CRD for Workflow, which
lets you create Workflow objects in the same way you create Pods, Deployments, or other Kubernetes resources.
The Workflow Controller is a Kubernetes application that watches for new or updated Workflow objects. When it sees one,
it schedules and manages the steps of that Workflow by updating its status on the cluster. A Workflow is therefore a
live object on the cluster that represents an individual (past or present) run – it contains the templates that are
running or have run, their statuses and outputs, the amount of resources used, and more – all stored within its YAML
specification.
Hera Classes
Hera provides many specialised classes in hera.workflows. You will see the Argo Workflows spec has been transformed
into powerful Python classes. Hera also provides classes autogenerated from the spec in hera.workflows.models.
Use Any Function on Argo
We can use Hera’s script decorator to turn any user-defined function into a
Script template, which is mirrored in Hera as the
Script class.
The script Decorator
The script decorator can take the kwargs that a Script can take, including image,
volumes, env, and many more. This is how we can specify a different image of Python to use instead of the default
python:3.10 for your script:
Alternatively, you can specify this image just once by using the global_config.image variable, and it will be used for
all script templates automatically:
from hera.shared import global_config
global_config.image = "python:3.13"
@script() # "echo" will use python:3.13
def echo(message: str):
print(message)
@script() # "echo_twice" will also use python:3.13
def echo_twice(message: str):
print(message)
print(message)
The Workflow Context Manager
The Workflow context manager acts as a scope under which template Hera objects can be declared, which include
Containers, Scripts, DAGs and more. You
can provide values for the Workflow itself:
generate_nameis used by Argo to create a name by appending a random 5 character suffix, so you may see this Workflow run with a name likehello-world-vmsz5.entrypointtells Argo which template to run upon submission.namespaceis the Kubernetes namespace you want to run the Workflow in.workflows_serviceis Hera’s REST API submission service.
The Steps Context Manager
A Steps template is the second template type of this example. The Steps template is known as a “template invocator”,
which is used to coordinate other templates, mainly Containers and Scripts, to do the actual work. In Hera, the Steps
class is a context manager; it automatically arranges your templates in the order that you add them, with each template
invocation known as a Step.
Clearly, echo takes a message, but we are passing in an arguments; this is actually syntactic sugar. Compare the
two snippets below which are functionally equivalent:
The “callable” syntax for your script templates intends to cut down boilerplate as much as possible, while keeping the code intuitive.
Submit the Workflow
Finally, with the workflow defined, the actual submisson occurs on
This uses the WorkflowsService to submit to Argo using its REST API, so w.create() can be thought of as running
argo submit from the CLI.
Generate the YAML
It’s important to recognise that Hera is a translation layer for Argo Workflows, which only understands YAML – the YAML Workflow should be considered the golden source when debugging.
You can generate the YAML for this Workflow using w.to_yaml(), or w.to_file(name="hello-world.yaml"):
See the YAML for this Workflow.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-world-
namespace: argo
spec:
entrypoint: steps
templates:
- name: steps
steps:
- - name: echo
template: echo
arguments:
parameters:
- name: message
value: Hello world!
- name: echo
inputs:
parameters:
- name: message
script:
image: python:3.10
source: |-
import os
import sys
sys.path.append(os.getcwd())
import json
try: message = json.loads(r'''{{inputs.parameters.message}}''')
except: message = r'''{{inputs.parameters.message}}'''
print(message)
command:
- python