102 lines
3.2 KiB
Python
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
|
|
)
|