Self-hosted service
argoproj-labs/hera avatar
argoproj-labs/hera

Hera: building Argo Workflows from Python instead of YAML

Hera makes Python code easy to orchestrate on Argo Workflows through native Python integrations. It lets you construct and submit your Workflows entirely in Python. ⭐️ Remember to star!

939 stars128 forksPythonApache-2.0

At a glance

What is it?
Hera is the Python SDK that turns decorated functions into Argo Workflows templates and submits them to a cluster. It fits teams already running Argo Workflows who want their orchestration logic to live in the same language as their business logic.
Who is it for?
Adopt Hera if you already run an Argo Workflows server and your pipeline authors write Python; skip it if you have no Argo server to submit to, since the README states the project requires one.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The YAML authoring problem Hera is aimed at

Argo Workflows is configured through YAML manifests. For a pipeline with a handful of steps that is manageable. For a DAG with many branches, shared templates, parameter passing between nodes, and per-task resource settings, the manifest becomes a large document that no linter fully protects you from. The failure mode is familiar: a typo in a template reference, or an argument wired to the wrong node, surfaces at submission time or halfway through a run rather than in your editor.

Hera targets that gap. Its README describes it as "the go-to Python SDK to make Argo Workflows simple and intuitive," and the pitch is that you construct and submit workflows entirely in Python. The intended user is a Python developer who has an Argo Workflows server on Kubernetes and would rather express a pipeline as function calls and operator chaining than as nested YAML. The README's own framing of the split is that "orchestration logic lives outside of business logic": the function body is the work, the surrounding block is the graph.

This is not a replacement for Argo Workflows. It is a client and a code generator for it. If you are not running Argo, Hera has nothing to submit to.

The @script decorator and the >> operator

The core mechanism is the script decorator. A plain Python function annotated with @script() becomes a reusable Script template. The README's at-a-glance example defines echo(message: str), which prints its argument, and then reuses that single template four times inside a DAG named diamond.

The orchestration block is a context manager. You open a Workflow with generate_name and entrypoint, then open a DAG inside it, then instantiate the decorated function once per node, passing arguments as a dictionary. Execution order is expressed with the shift operator: A >> [B, C] >> D. The list on the right of the first shift means B and C both depend on A, and both feed D. That is a compact encoding of a fan-out and fan-in, and it is the part that reads better than the equivalent YAML.

The final line, w.create(), is the submission step. The workflow object is not written to disk and handed to a CLI; it is posted to the Argo server. Two other output paths are documented: Workflow.to_yaml(*args, **kwargs), available when the yaml extra is installed, and a CLI that can convert in both directions. The README describes the CLI as supporting conversion of workflows "between YAML and Python source codes," with hera generate yaml --help and hera generate python --help as the entry points. That matters for migration: an existing hand-written manifest can be turned into Hera code rather than retyped.

What the material does not show is how the decorator handles dependencies beyond the standard library, or how it packages a function's imports into the container image. The README does not cover that, so treat it as something to check in the walk-through before assuming it is automatic.

Authentication and the localhost:2746 starting point

Hera assumes the Argo server sits behind an authentication layer, and the README states that submission requests are authenticated with a Bearer token. That assumption is the first thing to resolve, because it determines how much setup sits between writing the workflow and running it.

The documented shortcut is port forwarding. If you forward your Argo server deployment to localhost:2746, workflow submission works without the authentication layer. The README's example pairs that with the argo CLI installed and uses ArgoCLITokenGenerator as the token source. Configuration goes through global_config: you set global_config.host to "http://localhost:2746" and global_config.token to the generator class, then call w.create().

That combination is convenient for a laptop and is not a deployment story. For anything shared, you need a real token source, and the README points to a dedicated authentication walk-through rather than spelling out the options in the main document. If your environment issues short-lived tokens, the question of how the generator refreshes them is answered in that walk-through, not here.

One structural detail worth noting: the host and token live on a global config object, not on the Workflow. That means a script that talks to two different Argo servers has to mutate global state between submissions, or construct a service object directly. The README does not present a per-workflow override, so this is a design constraint to plan around rather than a bug.

Installation and the optional extras

The base install is pip install hera from PyPI. The README also gives a source install: python -m pip install git+https://github.com/argoproj-labs/hera --ignore-installed, which is the path you take if you need a commit that has not been released.

Three extras change what the library can do. hera[yaml] pulls in PyYAML, which is required for the yaml output format reached through Workflow.to_yaml. The README frames this as enabling GitOps practices and easier debugging, which is the honest use case: you generate the manifest, commit it, and let something else apply it. hera[async-client] pulls in httpx so the async_* workflow functions work through AsyncWorkflowsService. That is for code that submits many workflows concurrently and does not want to block a thread per request.

The third, hera[cli], installs Cappa and enables the generate commands. The README is explicit that this is "an experimental feature and subject to change." Take that at face value. If your plan is to build a pipeline that round-trips YAML through hera generate on every commit, you are depending on an interface the maintainers have reserved the right to break, and the 7.0.0 and 6.0.0 major releases in 2026 show that breaking changes do happen on this project.

Where Hera is the wrong tool

The hard requirement is stated plainly: Hera requires an Argo Workflows server deployed to a Kubernetes cluster. There is no local execution mode described in the README, no simulator, and no dry-run that tells you whether a DAG is valid before it reaches the server. If your team does not run Argo, Hera is not a lighter alternative to it; it is a client with nothing to connect to.

A second boundary is the abstraction itself. Because Hera generates Argo manifests, anything Argo cannot express is also beyond Hera. The README claims "full access to its capabilities," which is a reasonable design goal, but it also means you inherit Argo's concepts: templates, entrypoints, arguments, and the scheduling semantics of the controller. A team hoping to avoid learning Argo by adopting Hera will instead be debugging Argo through a Python layer, which is a worse position than reading the manifest directly.

The third case is small and static. If your workflow is four containers in a fixed sequence and it changes twice a year, a checked-in YAML file reviewed in a pull request is easier to reason about than a Python program whose output you have to reconstruct. Hera's value scales with the complexity of the graph and the frequency of change. Below that threshold it adds a dependency and a generation step without removing much work.

Finally, the global config object is a real constraint for multi-tenant tooling. Code that submits on behalf of different users or to different clusters has to manage that global state carefully, and the README does not describe a supported pattern for it.

How Hera compares to writing manifests by hand

The obvious alternative is authoring Argo Workflows YAML directly and applying it with kubectl or Argo CD. The difference in approach is where the graph is defined. In YAML, the graph is the document: you declare templates and a DAG whose tasks list names and dependencies, and correctness is a matter of matching strings across a file. In Hera, the graph is control flow in a Python program: the decorated function is the template, the DAG context manager is the graph, and dependencies are operator expressions.

That shift buys you the Python toolchain. Functions can be imported from a module, parameterised, and composed; the graph can be built by a loop or a conditional rather than by copy-pasting task blocks. It also buys you type annotations on the function signature, which the README's echo(message: str) example uses.

What it costs is a generation step and a layer of indirection. When something goes wrong at runtime, the manifest the controller saw is not the file you edited; you have to reproduce it, which is where Workflow.to_yaml and the CLI's generate commands earn their place. Teams that already have mature YAML review practices, templating with Helm or Kustomize, and a GitOps controller watching a repository may find the Python path adds a build artifact without removing the review burden.

The honest split is this: Hera wins when the graph is dynamic or large enough that hand-editing is error-prone. Plain YAML wins when the graph is small, stable, and already covered by your existing review and deployment process.

Release cadence, licence, and what to verify

The project ships major versions at a steady clip. The supplied release list shows 7.1.0 in August 2026, 7.0.0 in June 2026, and 6.0.0 in March 2026. Two majors in six months is a signal about upgrade cost: pinning a version range and reading the release notes before bumping is the practical approach, particularly if you rely on the experimental CLI. The library is Apache-2.0 licensed, which permits commercial use and modification; the repository does not carry a separate licence file note in the material provided, so confirm the terms in the repository itself before redistributing a modified copy. That is a pointer to where to look, not legal advice.

Maintenance cost is mostly the version pin. The base dependency footprint is small, and the extras are opt-in, so an install that only needs @script and Workflow.create() carries little beyond the library itself. The recurring cost is the upgrade cycle and whatever you build on the CLI, which the README marks as subject to change.

Before adopting, verify these against your own environment. First, the Argo server version you run and whether the manifests Hera emits for that version are accepted. Second, the authentication path: the README's localhost:2746 port-forward example with ArgoCLITokenGenerator is a starting point, and the authentication walk-through is where the production options are described. Third, whether you need hera[yaml] or hera[cli], because the first determines whether you can inspect the generated manifest without a round trip and the second determines whether you are depending on an interface the maintainers have flagged as unstable. A team that runs Argo, writes Python, and has a graph too tangled to maintain as YAML will get value here. A team without an Argo server, or with a pipeline that has not changed in a year, will not.

Editorial conclusion

Adopt Hera if you already run an Argo Workflows server and your pipeline authors write Python; skip it if you have no Argo server to submit to, since the README states the project requires one. Before committing, verify three things against your own cluster: that your Argo server version accepts what the SDK emits, that your chosen authentication path works (ArgoCLITokenGenerator against a port-forwarded localhost:2746 is the documented starting point), and whether you need the yaml or cli extras, because hera generate yaml is marked experimental in the README.

Official sources

  1. argoproj-labs/hera on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes