Source code for shinobi.steps.decorator
"""`@shinobi.step`: bind an orchestration function to a Scope.
Returns a `StepRef` (the same type `@recipe.step` produces) -- the single
carrier of the orchestration function. There is no global function
registry: `func` travels on the StepRef itself, so two functions over one
Scope, or same-named functions in different recipes, never collide.
The decorated name is callable and dispatches with `ctx` passed as the
first positional argument; the function returns either the `StepResult`
from `ctx.run()` or `None` (auto-run). The function's own signature is
never introspected -- `scope.inputs_model` is the schema authority.
"""
from __future__ import annotations
from typing import Any, Callable
from shinobi.steps.schema import Scope, StepRef
[docs]
def step(
scope: Scope,
*,
backend: str | None = None,
name: str | None = None,
**params: Any,
) -> Callable[[Callable], StepRef]:
"""Decorate a function with an existing Scope (Cab or Recipe). See the
module docstring.
"""
def decorator(func: Callable) -> StepRef:
"""Bind `func` as the orchestration function for `scope`.
Args:
func: The orchestration function to bind. Its own signature is
never introspected.
Returns:
A `StepRef` carrying `scope`, `func`, and the step's params.
"""
bound_scope = scope.with_backend(backend)
return StepRef(name=name or func.__name__, step=bound_scope, func=func, params=params)
return decorator