Hello World¶
The simplest possible Groundhog script demonstrating basic remote execution.
Full Example¶
# /// script
# requires-python = ">=3.12,<3.13"
# dependencies = []
#
# [tool.uv]
# exclude-newer = "2025-12-02T19:48:40Z"
# (3)!
#
# [tool.hog.anvil] # Anvil Multi-User Globus Compute Endpoint
# endpoint = "5aafb4c1-27b2-40d8-a038-a0277611868f"
# account = "my-anvil-account"
# walltime = "00:30:00"
#
# ///
import groundhog_hpc as hog
@hog.function(endpoint="anvil") # (1)!
def hello_world(name: str = "World") -> str:
"""Example function that can be run remotely on your HPC cluster."""
return f"Hello, {name}!"
@hog.harness() # (2)!
def main():
"""Main harness that orchestrates remote function calls.
Run the 'main' harness with: hog run hello_world.py
Run another harness with: hog run hello_world.py [harness]
"""
# .remote() blocks until the function completes
# use .submit() to return a future instead
result = hello_world.remote("World")
print(f"Result: {result}")
-
The
@hog.function()decorator makes this function executable remotely. Theendpoint="anvil"parameter tells Groundhog to use configuration from the[tool.hog.anvil]block in the PEP 723 metadata. -
The
@hog.harness()decorator marks this as an orchestrator function that can be run withhog run, e.g.hog run hello_world.py some_harness -
Optional, but highly recommended for reproducibility, restricting
uvto only install package versions released before the timestamp.
Anatomy of a Groundhog (Script):¶
PEP 723 Metadata¶
The comment block at the top configures the remote execution environment:
# /// script
# requires-python = ">=3.12,<3.13"
# dependencies = []
# (1)!
#
# [tool.hog.anvil] # Anvil Multi-User Globus Compute Endpoint
# endpoint = "5aafb4c1-27b2-40d8-a038-a0277611868f"
# account = "my-anvil-account"
# walltime = "00:30:00"
# ///
-
Note that we do not need to specify
groundhog-hpc(installed automatically) norglobus-compute-endpoint(not needed in the isolated environment) -
requires-python: The Python version that will be used on the remote endpoint dependencies: Python packages to install (empty in this simple example)[tool.hog.anvil]: Endpoint-specific configuration including the Globus Compute endpoint UUID and HPC scheduler parameters
The Function¶
@hog.function(endpoint="anvil")
def hello_world(name: str = "World") -> str:
"""Example function that can be run remotely on your HPC cluster."""
return f"Hello, {name}!"
The @hog.function() decorator wraps this function so it can be called in multiple ways:
hello_world("Alice")- Direct local call (no decoration, runs immediately)hello_world.remote("Alice")- Remote blocking call (submits to HPC, waits for result)hello_world.submit("Alice")- Remote async call (returns a GroundhogFuture)hello_world.local("Alice")- Local subprocess call (same as remote, but in an isolated local subprocess)
The Harness¶
Harnesses are orchestrator entry-point functions that coordinate remote execution. They:
- Are invoked with
hog run my_script.py [harness] - Take no arguments
- Can call
.remote()or.submit()on decorated functions
Running the Example¶
Run the harness with:
You'll see output like:
To use a different endpoint, you can override the configuration at call-time:
result = hello_world.remote(
"World",
endpoint='another-endpoint-uuid',
user_endpoint_config={"account": "another-account"} # (1)!
)
- The final
user_endpoint_configdict is passed directly to the Globus Compute Executor. TheGroundhogFuturereturned by.submitalso records the config passed to the executor.
Next Steps¶
- Dependencies - Learn how to add external packages
- Parallel Execution - Execute multiple functions concurrently