Skip to content

Operations

Operations define the computational units of an experiment. Use the @operation decorator to wrap functions that receive context, parameters, seeds, and a capture interface.

metalab.operation

Operation decorator and wrapper.

The @operation decorator marks a function as a metalab operation, adding metadata and providing a consistent interface.

OperationWrapper

OperationWrapper(func: Callable[..., RunRecord], name: str | None = None)

Wrapper around an operation function.

Provides:

  • Metadata (name)
  • Consistent interface
  • Code hash for provenance
  • Automatic signature inspection (only inject requested parameters)

Initialize the wrapper.

Parameters:

Name Type Description Default
func Callable[..., RunRecord]

The operation function.

required
name str | None

The operation name (defaults to function name).

None

code_hash property

code_hash: str

A hash of the operation's source code.

Useful for provenance tracking. Returns empty string if source cannot be retrieved.

name property

name: str

The operation name.

ref property

ref: str

Get a reference string for this operation.

Format: "module:name" for reconstruction in workers.

__call__

__call__(context: FrozenContext, params: dict[str, Any], seeds: SeedBundle, runtime: Runtime, capture: Capture) -> RunRecord

Allow calling the wrapper directly.

run

run(context: FrozenContext, params: dict[str, Any], seeds: SeedBundle, runtime: Runtime, capture: Capture) -> RunRecord

Execute the operation.

Only injects parameters that the function signature requests. This allows operations to declare only the parameters they need:

@metalab.operation
def my_op(params, seeds, capture):  # Only request what you need
    ...

Parameters:

Name Type Description Default
context FrozenContext

The frozen context.

required
params dict[str, Any]

The resolved parameters.

required
seeds SeedBundle

The seed bundle.

required
runtime Runtime

The runtime context.

required
capture Capture

The capture interface.

required

Returns:

Type Description
RunRecord

A RunRecord describing the run outcome.

import_operation

import_operation(ref: str) -> OperationWrapper

Import an operation from a reference string.

Parameters:

Name Type Description Default
ref str

Reference in format "module:name".

required

Returns:

Type Description
OperationWrapper

The OperationWrapper instance.

Raises:

Type Description
ImportError

If the module cannot be imported.

AttributeError

If the operation cannot be found.

operation

operation(func: Callable[..., Any]) -> OperationWrapper
operation(func: None = None, *, name: str | None = None) -> Callable[[Callable[..., Any]], OperationWrapper]
operation(func: F | None = None, *, name: str | None = None) -> OperationWrapper | Callable[[F], OperationWrapper]

Decorator to mark a function as a metalab operation.

Can be used with or without arguments:

@metalab.operation
def my_op(params, capture): ...

@metalab.operation()
def my_op(params, capture): ...

@metalab.operation(name="custom_name")
def my_op(params, capture): ...

The decorated function can request any subset of these parameters:

  • context: The frozen context (shared read-only data)
  • params: The resolved parameters for this run
  • seeds: The seed bundle for reproducible randomness
  • runtime: Runtime context (scratch dir, resource hints)
  • capture: Interface for recording metrics and artifacts

Only include the parameters your operation needs—unused ones can be omitted.

Parameters:

Name Type Description Default
func F | None

The function to decorate (when used without parentheses).

None
name str | None

Optional operation name (defaults to function name).

None

Returns:

Type Description
OperationWrapper | Callable[[F], OperationWrapper]

An OperationWrapper or a decorator that creates one.

Example
# Simplest form - uses function name as operation name
@metalab.operation
def estimate_pi(params, seeds, capture):
    n = params["n_samples"]
    rng = seeds.numpy()
    x, y = rng.random(n), rng.random(n)
    pi_est = 4.0 * (x**2 + y**2 <= 1).mean()
    capture.metric("pi_estimate", pi_est)

# With custom name
@metalab.operation(name="pi_mc")
def estimate_pi(params, seeds, capture):
    ...

# Full signature also works
@metalab.operation
def full_operation(context, params, seeds, runtime, capture):
    ...

metalab.OperationWrapper

OperationWrapper(func: Callable[..., RunRecord], name: str | None = None)

Wrapper around an operation function.

Provides:

  • Metadata (name)
  • Consistent interface
  • Code hash for provenance
  • Automatic signature inspection (only inject requested parameters)

Initialize the wrapper.

Parameters:

Name Type Description Default
func Callable[..., RunRecord]

The operation function.

required
name str | None

The operation name (defaults to function name).

None

code_hash property

code_hash: str

A hash of the operation's source code.

Useful for provenance tracking. Returns empty string if source cannot be retrieved.

name property

name: str

The operation name.

ref property

ref: str

Get a reference string for this operation.

Format: "module:name" for reconstruction in workers.

__call__

__call__(context: FrozenContext, params: dict[str, Any], seeds: SeedBundle, runtime: Runtime, capture: Capture) -> RunRecord

Allow calling the wrapper directly.

run

run(context: FrozenContext, params: dict[str, Any], seeds: SeedBundle, runtime: Runtime, capture: Capture) -> RunRecord

Execute the operation.

Only injects parameters that the function signature requests. This allows operations to declare only the parameters they need:

@metalab.operation
def my_op(params, seeds, capture):  # Only request what you need
    ...

Parameters:

Name Type Description Default
context FrozenContext

The frozen context.

required
params dict[str, Any]

The resolved parameters.

required
seeds SeedBundle

The seed bundle.

required
runtime Runtime

The runtime context.

required
capture Capture

The capture interface.

required

Returns:

Type Description
RunRecord

A RunRecord describing the run outcome.