Files
lda-wf/src/wf_core/runtime/input_bindings.py
T

102 lines
3.2 KiB
Python

from __future__ import annotations
from collections.abc import Mapping, Sequence
from typing import Any
from wf_core.errors import WorkflowExecutionError
from wf_core.local_paths import LocalPathError, set_local_value
from wf_core.models.input_bindings import (
InputExpression,
InputExpressionBinding,
InputPathBinding,
InputValueBinding,
StepInputBinding,
)
from wf_core.models.json_values import JsonValue
from wf_core.runtime.input_sources import (
GraphSourceResolver,
SourceResolver,
resolve_composed_expression,
)
def resolve_input_expression(
expression: InputExpression,
*,
state: Mapping[str, Any],
workflow_input: Mapping[str, Any],
context: Mapping[str, Any],
label: str,
location: str,
) -> JsonValue:
"""Resolve one composite expression while preserving its payload location."""
resolver = GraphSourceResolver(
state=state, workflow_input=workflow_input, context=context
)
return resolve_composed_expression(
expression, resolver=resolver, label=label, location=location
)
def resolve_input_expression_with_resolver(
expression: InputExpression,
*,
resolver: SourceResolver,
label: str,
location: str,
) -> JsonValue:
"""Resolve one expression through an explicit typed source resolver."""
return resolve_composed_expression(
expression, resolver=resolver, label=label, location=location
)
def resolve_step_input_bindings_with_resolver(
bindings: Sequence[StepInputBinding],
*,
resolver: SourceResolver,
label: str,
) -> dict[str, Any]:
"""Build one node-local payload through an explicit graph resolver."""
payload: dict[str, Any] = {}
for binding in bindings:
location = str(binding.target)
if isinstance(binding, InputValueBinding):
value = binding.value
elif isinstance(binding, InputPathBinding):
try:
value = resolver.resolve_path(binding.path)
except (ValueError, WorkflowExecutionError) as exc:
raise WorkflowExecutionError(f"{label} {location}: {exc}") from exc
elif isinstance(binding, InputExpressionBinding):
value = resolve_input_expression_with_resolver(
binding.expression,
resolver=resolver,
label=label,
location=location,
)
else:
raise WorkflowExecutionError(f"unsupported input binding for {label}")
try:
set_local_value(payload, binding.target, value)
except LocalPathError as exc:
raise WorkflowExecutionError(f"{label} {location}: {exc}") from exc
return payload
def resolve_step_input_bindings(
bindings: Sequence[StepInputBinding],
*,
state: Mapping[str, Any],
workflow_input: Mapping[str, Any],
context: Mapping[str, Any],
label: str,
) -> dict[str, Any]:
"""Build one node-local payload from simple or composite input bindings."""
resolver = GraphSourceResolver(
state=state, workflow_input=workflow_input, context=context
)
return resolve_step_input_bindings_with_resolver(
bindings, resolver=resolver, label=label
)