Manage Layouts¶
Layouts are the saved dashboard configurations you build in the Zelos App. agent.layouts gives you the same CRUD surface from Python — useful for provisioning team dashboards from code, backing them up, or generating them from templates.
Layouts live in Zelos Cloud, so the agent must be logged in (zelos login). The snippets below assume an agent connected via connect():
List and inspect¶
for layout in agent.layouts.list():
scope = "personal" if layout.is_personal else "team"
print(f"{layout.name:30} {scope:8} {layout.id}")
Each Layout carries id, name, data (the panel configuration as a dict), is_personal, team_id and team_slug, user_id (the owner of a personal layout, None for a team layout), created_at and updated_at (RFC 3339 strings), the owner's email, and updated_by_email. Fetch one by id with agent.layouts.show(id).
Create¶
created = agent.layouts.create("My Dashboard", {"panels": []})
print(created.id)
# Scope to yourself instead of the team
personal = agent.layouts.create("Scratch", {"panels": []}, is_personal=True)
data accepts any JSON-serializable dict. The easiest way to author one is to build the layout in the app, then copy its data from show().
Update¶
update() patches only what you pass — omitted fields keep their current values (the SDK fetches the current layout first when needed):
agent.layouts.update(created.id, name="Renamed Dashboard")
agent.layouts.update(created.id, data={"panels": []}, is_personal=True)
Passing no fields at all raises ValueError.
Delete¶
Version history¶
Every content-changing save records a version (create is version 1; no-op saves and personal/shared toggles don't version). The last 100 versions are kept per layout.
for v in agent.layouts.versions(created.id):
marker = f" (restored from v{v.restored_from_version})" if v.restored_from_version else ""
print(f"v{v.version:<4} {v.name:30} {v.created_at} {v.created_by_email or ''}{marker}")
versions() returns metadata only, newest first. Fetch a specific version's full data snapshot with show_version():
Restore a previous version with restore(). The restored state is appended to the history as a new version (with restored_from_version provenance) — history is never rewritten, so the pre-restore state stays restorable. Restoring a version identical to the current state is a no-op:
Name a version¶
Label a version worth keeping with set_version_label(). Named versions show their label in versions() and are kept forever — the 100-version retention never prunes them. Each layout can hold at most 40 named versions; naming another raises ValueError from the server until you clear an existing label:
agent.layouts.set_version_label(created.id, 3, "Golden config")
# Pass None to clear the label (the version becomes prunable again)
agent.layouts.set_version_label(created.id, 3, None)
A layout with no versions
A layout can have an empty versions() list. Its next update records the current state as version 1, then the new state as version 2, so the state you replace stays restorable.
Errors¶
| Exception | When |
|---|---|
ValueError |
Malformed layout id, non-JSON-serializable data, an update() with no fields, or a version number outside 1–4294967295 — all raised before any network call. Also raised when the server rejects a set_version_label(): a label longer than 100 characters, or a layout that already has 40 named versions. |
AgentError |
Layout or version not found, agent not logged in, or the call failed. |