Full Sample¶
This comparison is useful when deciding whether a surface should stay YAML-first or whether it needs programmatic assembly in the render function. The YAML version is shorter and easier to scan when the structure is static. The Python version is the right tool when the surface shape itself is computed.
One important constraint matters here: the current YAML loader supports the surface structure itself, but it does not currently read builder-only root sections such as a declarative data_model or page/global store seed. If your surface needs initial set_data(...) or set_store(...), load the YAML first and then seed those values from Python.
The same caution applies to template: the loader accepts it, but for most module UI that value is usually chosen by the render flow that prepares the surface, not by a minimal YAML fragment. In a small YAML-only example, including template: full often creates more confusion than value.
The same is true for root surface_id. It does not identify one component. It binds the whole builder to one target surface, which is a different concern from component ids such as title. In a minimal sample, it is usually clearer to keep component ids in YAML and keep the surface binding in Python.
builder = sdk.ui.Builder()
builder.set_template("full", session=session)
builder.set_surface("users_main")
builder.set_data("/filters/search", "Users")
builder.set_store("/drafts/search", "", scope="page")
builder.add(
sdk.ui.Text(
"title",
sdk.ui.bound.data("/filters/search", default=""),
)
)
payload = builder.build_surface_update_payload("users_main")components:
- kind: Text
id: title
text: "@data/filters/search"builder = sdk.ui.load("ui/yaml/users_main")
builder.set_surface("users_main")
builder.set_template("full", session=session)
builder.set_data("/filters/search", "Users")
payload = builder.build_surface_update_payload(builder.surface_id)Practical Notes¶
Builderis part of theuidomain, not a separate root-level SDK shortcut.- Use
Builderdirectly when the UI cannot be expressed entirely through YAML. - The current YAML loader understands root keys such as
template,surface_id, andcomponents, but not a declarative rootdata_modelor builder store seed. - Root
surface_idis the target surface of the builder, not theidof one component. Keep those concepts separate in examples and in real code. - In practice, keep structural UI in YAML and keep builder concerns such as
set_surface(...),set_template(...),set_data(...), andset_store(...)in the Python render flow unless the YAML file genuinely needs to carry them. - When you load YAML with
sdk.ui.load(...), prefer putting structural UI in YAML and then callingset_data(...)/set_store(...)from Python for runtime state initialization. - Treat the builder data model as surface-scoped server state, not as a replacement for page/global stores.
- Prefer page/global stores for reactive UI state that should update without rebuilding the full surface.
- Use
set_data(...)for surface data model andset_store(...)for page/global client state. - Use
@data/...for surface data model bindings and@state/...for store bindings. - Prefer targeted property and collection updates over full surface rebuilds when the structure is already mounted.
- Pair this layer with
sdk.effectsfor action responses.