-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Problem
latch preview ignores the flow array in LatchMetadata. Workflows using flow= (with Section, Spoiler, Params, etc.) render with the old default layout and a "Hidden Parameters" fallback instead of their defined UI structure. This forces a full latch register cycle just to verify layout changes.
Root cause
preview.py sends only per-parameter data via wf.interface.to_flyte_idl().inputs. The workflow-level __metadata__ dict — which contains the flow array — is serialized into the workflow's docstring by _inject_metadata() but is never extracted or forwarded by the preview service.
The upsertWorkflowPreview mutation only accepts argAccountId and argInputs, with no field for workflow-level metadata.
Proposed fix
SDK side (src/latch_cli/services/preview.py): Extract the __metadata__ block from the workflow docstring and pass it to the mutation.
import yaml
# After obtaining `wf`, extract workflow-level metadata from docstring
metadata = {}
docstring = wf.python_interface.docstring or ""
if "__metadata__:" in docstring:
yaml_start = docstring.index("__metadata__:")
try:
parsed = yaml.safe_load(docstring[yaml_start:])
if isinstance(parsed, dict):
metadata = parsed.get("__metadata__", {})
except yaml.YAMLError:
pass
# Include in mutation
execute(
gql.gql("""
mutation UpdatePreview($accountId: BigInt!, $inputs: String!, $metadata: JSON) {
upsertWorkflowPreview(
input: { argAccountId: $accountId, argInputs: $inputs, argMetadata: $metadata }
) {
clientMutationId
}
}
"""),
{
"accountId": current_workspace(),
"inputs": MessageToJson(wf.interface.to_flyte_idl().inputs),
"metadata": metadata if metadata else None,
},
)Backend side: Add an optional argMetadata parameter (JSON) to the upsertWorkflowPreview mutation and persist it so the preview page can use flow for rendering, the same way registered workflows do.
Fallback: When metadata is None or flow is absent, behavior is unchanged — the frontend falls back to per-parameter _tmp.hidden and section_title layout.
Reproduction
from latch.resources.workflow import workflow
from latch.types.metadata import LatchMetadata, LatchParameter, Params, Section, Spoiler
metadata = LatchMetadata(
display_name="Test Spoiler Preview",
parameters={
"name": LatchParameter(display_name="Name"),
"advanced_opt": LatchParameter(display_name="Advanced Option"),
},
flow=[
Section("Inputs", Params("name")),
Spoiler("Advanced", Params("advanced_opt")),
],
)
@workflow(metadata)
def test_wf(name: str = "hello", advanced_opt: int = 42) -> str:
...Run latch preview . — sections and spoiler are not rendered.