Elements reference

Runtime, publish, execute en logs

Deze pagina behandelt alles na het editorwerk: publiceren, versioning, runtime vars/secrets, test execute, execution logs en integratie met datasources.

1. Publish en versions

OnderdeelBeschrijving
PublishValideert draft, bouwt dependencies en maakt een nieuwe version.
latestVersionElementmetadata verwijst na publish naar nieuwste version.
Version statusBevat build/publish uitkomst per versie.
Build metricsWheels count en build duration worden opgeslagen.
Als Git sync Apply een wijziging uit de repo terugschrijft naar een bestaand gepubliceerd Element, wordt alleen de draft bijgewerkt. De huidige gepubliceerde version blijft actief totdat je handmatig opnieuw publiceert. In het Elements-overzicht zie je dat als Updated draft.

Versions tabel

  • Version, Status, Published.
  • Wheels (aantal dependency artifacts).
  • Build (ms).

2. Runtime vars en runtime secrets

Element runtime dialoog
Runtime testen is de snelste manier om codefouten te scheiden van page- of datasourcefouten.
Tenant runtime store
Beheer runtime store centraal en wijzig waarden bewust, omdat afhankelijkheden verspreid kunnen zijn.
TypeInputGedrag
Runtime varID + JSON valueJSON moet valide zijn; leesbaar met getVar().
Runtime secretID + nieuwe waarde bij opslaanWrite-only opslag; leesbaar met getSecret().
Runtime writebacksetVar() in codeNieuwe waarde wordt direct naar de runtime store geschreven.

3. Test execute

VeldBeschrijving
versionLeeg betekent latest published version.
timeoutSecondsBereik 1-3600, default 3600.
paramsJSON object met inputparameters. Element widget-runs en widget-test-runs voegen params.__dashview.theme.mode toe met light of dark. Interactieve Element widgets sturen acties terug via params.__dashview.interaction en vorige state via params.__dashview.state.
{
  "version": "",
  "timeoutSeconds": 3600,
  "params": {
    "from": "2026-01-01",
    "to": "2026-01-31",
    "country": "NL",
    "__dashview": {
      "theme": {
        "mode": "light",
        "isDark": false,
        "isLight": true
      },
      "widget": {
        "id": "widget_dynamic_html",
        "type": "element"
      }
    }
  }
}

4. HTTP Elements

Endpoints en authenticatie

  • trigger-Elements zijn one-shot handlers via POST /element/{elementId}.
  • Elke request start een normale Element-run en eindigt zodra de entrypoint klaar is.
  • server-Elements publiceren een ASGI/FastAPI-app via dezelfde gateway: /element/{elementId} en /element/{elementId}/{path...}.
  • Server Element-paden kunnen HTTP requests, SSE streaming responses en WebSocket-verbindingen afhandelen. De runtime houdt de child server warm zolang er verkeer is en stopt hem na ongeveer 15 minuten idle; de volgende request start hem opnieuw.
  • Gebruik een Access key als bearer token. De call draait als die gebruiker binnen de actieve tenantcontext en behoudt datasource- en forced-filterrechten.
InputWaar beschikbaarBeschrijving
params.requestrun(params)Request envelope met method, path, query, headers, body/json/form en bodygrootte.
params.__dashview.requestrun(params)Zelfde envelope onder de Dashview namespace.
context.requestrun(context, params)Zelfde envelope voor code die runtime metadata via context leest.
def run(context, params):
    request = context["request"]
    return {
        "statusCode": 200,
        "headers": {"x-element": "trigger"},
        "json": {"ok": True, "payload": params.get("json")},
    }
from fastapi import FastAPI

app = FastAPI()

@app.post("/logs")
async def ingest_logs(payload: dict):
    dataSources.appendRows("chargepoint_logs", [payload])
    return {"ok": True}
Authorization en cookie-achtige headers worden niet aan Element-code doorgegeven. Server Elements draaien in dezelfde Element runtime als normale Elements, dus ingebouwde helpers zoals queryDataSources en dataSources.appendRows zijn beschikbaar vanuit de ASGI-app.

5. Live datasource streaming

Wanneer gebruik je dit?

  • Gebruik dit als een Element tijdens de run al widget-data moet tonen of vervangen.
  • Dit werkt via een datasource met connector type element en Default data format = Live stream, of direct via een gepubliceerd Element van type stream_data.
  • De equivalente raw datasource config is dataFormat: "livestream". Legacy configs met streamMode: "commands" blijven ondersteund.
HelperDoelGedrag in widgets
emitProgress(...)Status/progress doorgevenGeeft progress events door; voegt geen datasource rows toe.
appendRows([...])Nieuwe rows toevoegenWidgets zien extra rows terwijl het Element nog draait.
replaceRows([...])Volledige dataset vervangenWidgets schakelen over naar de nieuwe set rows.
clearRows()Huidige rows leegmakenMaakt de live datasource tabel leeg voordat nieuwe rows volgen.

Execution-logsamenvattingen en detailchunks worden in Firestore onder tenants/{tenantId}/runtimeLogs/_tenant/elements/{elementId}/elementExecutionLogs opgeslagen en via Firestore TTL op expireAt bewaard.

Belangrijke notities

  • Deze helpers zijn bedoeld voor datasource requests via /data/{id}/livestream, niet voor gewone snapshot/parquet loads.
  • Actieve dashboardfilters kunnen voor live-stream datasources en snapshot datasources met Snapshot bij elk verzoek als params worden doorgestuurd naar het Element.
  • Zet Filters als params doorgeven uit op een geschikte Element-datasource wanneer je die filterparams juist niet aan het Element wilt doorgeven.
  • De normale return value van je Element blijft bestaan, maar live widget-updates horen uit deze stream helpers te komen.
  • Gepubliceerde data- en stream_data-Elements zijn direct selecteerbaar als datasource in dashboards; een aparte datasource-doc is daarvoor niet verplicht.
def run(context, params):
    import time

    emitProgress(phase="starting", message="Start live run", progressPercent=0)
    clearRows()

    for step in range(1, 5):
        time.sleep(3)
        appendRows([{
            "step": step,
            "message": f"Tick {step}",
            "value": step * 10,
        }])
        emitProgress(
            phase="running",
            message=f"Step {step} van 4",
            progressPercent=step * 25,
        )

    return {"done": True}

Waar vind ik voorbeelden?

  • element-examples/command_stream_demo.py toont incrementele row updates.
  • element-examples/cloudrunlogs.py toont een langere append-only live tail.

6. Execution logs

KolomBeschrijving
TimeStarttijd van de run.
StatusToegestane waarden: success, error, failed.
SourceHerkomst (admin_test, datasource, flow, etc.).
VersionUitgevoerde version.
DurationRuntime duur in ms.
ErrorKorte foutsamenvatting.
View detailsVolledige payload incl. meta/stdout/stderr/result en vastgelegde logger-berichten.

Server Element requests

  • HTTP/SSE requests via de publieke Element gateway maken execution logs met source=server_http nadat de response body klaar is.
  • WebSocket-sessies maken een execution log met source=server_websocket wanneer de sessie sluit of faalt.
  • Request logs bevatten method, path, query string, request id, status, duur en websocket message counts. Bodies en headers worden niet opgeslagen.

Logger-output tijdens runs

  • Gebruik in Element-code de ingebouwde logger, bijvoorbeeld logger.info("Start refresh") of logger.error("API call mislukt").
  • Deze berichten verschijnen in de uitvoerlogdetails per run, inclusief severity, loggernaam en stacktrace bij logger.exception(...).
  • Gebruik dit voor controlepunten, externe API-fouten en business-validatie, zodat debugging niet alleen via stdout of traceback hoeft.

Integratie met datasources

  • Element connector roept dezelfde runtime aan met elementId, elementVersion, elementEntrypoint.
  • Request params kunnen direct worden doorgestuurd of hernoemd via requestParamMap.
  • Timeouts zijn configureerbaar per datasource via elementTimeoutSeconds.

7. Technical reference

JSON payload voorbeelden

Test execution payload voor een gepubliceerd Element:

{
  "version": "v_20260605090000_abcd12",
  "timeoutSeconds": 3600,
  "params": {
    "country": "NL",
    "limit": 20
  }
}

Element-backed cached datasource payload:

{
  "id": "orders-from-element",
  "name": "Orders from Element",
  "type": "element",
  "dataFormat": "parquet-remote",
  "elementId": "el_orders",
  "elementVersion": "v_20260605090000_abcd12",
  "elementEntrypoint": "run"
}

Live stream datasource payload:

{
  "id": "orders-live",
  "name": "Orders live",
  "type": "element",
  "elementId": "el_orders_live",
  "elementVersion": "v_20260605090000_abcd12",
  "elementEntrypoint": "run",
  "dataFormat": "livestream"
}

Duurzame datasource writes

Gebruik appendDataSourceRows of dataSources.appendRows wanneer een Element rows blijvend moet opslaan in een uplink/parquet-backed datasource voor latere dashboards, queries of andere Elements.

def run():
    rows = [{
        "createdAt": "2026-06-05T12:00:00Z",
        "status": "ok",
        "value": 123,
    }]
    result = dataSources.appendRows("element_event_store", rows, merge=True)
    return {"inserted": result["inserted"]}
  • Dit is iets anders dan live appendRows(); duurzame writes maken parquet parts via uplink.
  • De helper is alleen beschikbaar wanneer de execution context datasource write capability geeft.
  • Rows zijn append-only JSON-objecten en worden als batch verstuurd.
  • Optionele meta kan uplink auto-create velden bevatten zoals dataSourceName, dataFormat, parquetPartitionColumn en parquetPartitionGranularity.

Tenant-scoped GCS files

Gebruik de gcs-helpers wanneer een Element bestanden moet beheren die langer meegaan dan één request, bijvoorbeeld exports, rapportbijlagen of tijdelijke bestanden die later opnieuw gelezen moeten worden. De worker gebruikt de geconfigureerde file artifact/output bucket en forceert elk object onder filestore/{tenantId}/.... Een Element in tenant tenant-1 kan dus schrijven naar gs://dashview-cache/filestore/tenant-1/exports/report.json, maar niet naar een andere bucket of tenant-filestore-map.

def run():
    ref = gcs.upload(
        "exports/report.json",
        data={"status": "ready"},
        format="json",
        signedUrl=True,
        ttlSeconds=900,
    )
    text = gcs.download(ref["gcsUri"])
    signed = gcs.sign("exports/report.json", ttlSeconds=900)
    files = gcs.list("exports")
    gcs.delete("exports/old-report.json", ignoreMissing=True)
    return {
        "gcsUri": ref["gcsUri"],
        "rawHttpUrl": ref["rawHttpUrl"],
        "signedUrl": signed["signedUrl"],
        "fileCount": len(files),
        "downloaded": text,
    }

Een GCS parquet file wijzigen met DuckDB

Om edits terug te schrijven naar een tenantbestand download je het object naar workspace, laad je het in de geïnjecteerde DuckDB connection, draai je normale SQL zoals UPDATE, exporteer je een vervangend bestand en upload je dat terug naar hetzelfde GCS-pad met overwrite=True.

import base64
from pathlib import Path

def run(duckdb, workspace):
    object_path = "datasets/orders.parquet"
    work = Path(workspace)
    input_path = work / "orders.parquet"
    output_path = work / "orders.updated.parquet"

    downloaded = downloadGcsFile(object_path, asBytes=True)
    input_path.write_bytes(base64.b64decode(downloaded["dataBase64"]))

    duckdb.execute(
        "CREATE TABLE orders AS SELECT * FROM read_parquet(?)",
        [str(input_path)]
    )
    duckdb.execute("""
        UPDATE orders
        SET status = 'archived'
        WHERE status = 'closed'
    """)
    duckdb.execute(
        "COPY orders TO ? (FORMAT PARQUET)",
        [str(output_path)]
    )

    return uploadGcsFile(
        object_path,
        dataBase64=base64.b64encode(output_path.read_bytes()).decode("ascii"),
        contentType="application/vnd.apache.parquet",
        overwrite=True,
        metadata={"updatedBy": "element"},
    )
  • uploadGcsFile retourne metadata zoals uri, gcsUri, httpUrl, rawHttpUrl, bucket, object, relativePath, contentType en size.
  • httpUrl en rawHttpUrl zijn de ruwe Storage URL. Gebruik signedUrl of downloadUrl wanneer een browser of externe client tijdelijk toegang nodig heeft.
  • Volledige gs://-paden zijn toegestaan, maar alleen wanneer ze al naar de geconfigureerde bucket en huidige tenantmap wijzen.
  • Terugschrijven naar hetzelfde pad vervangt het object; gebruik een nieuw outputpad wanneer je versiebeheer of review voor vervanging nodig hebt.
  • Deze helpers geven geen extra tenant-, user- of datasource-rechten. Behandel signed URLs als gevoelige, kortlevende bearer URLs.

Element-local DuckDB

Elke Element-run krijgt een request-local DuckDB database op {workspace}/element.duckdb. Voeg een named duckdb-parameter toe aan de entrypoint om die connection te ontvangen, en voeg workspace toe wanneer het Element een schrijfbare scratch directory nodig heeft. Named entrypointparameters kunnen context/ctx, params/args, duckdb en workspace zijn; een entrypoint met **kwargs krijgt ze allemaal.

def run(params, duckdb, workspace):
    duckdb.execute(
        "CREATE TABLE totals AS SELECT 1 AS id, ? AS value",
        [params["value"]]
    )
    return {"table": "totals"}

Gebruik normale DuckDB connection-methods zoals duckdb.execute(...), duckdb.sql(...), duckdb.register(...) en duckdb.from_df(...). Deze lokale connection ziet alleen tabellen die het Element zelf maakt en tabellen die helpers laden. Gebruik queryDataSources voor tenant-scoped datasource reads zodat backend access checks en forced filters afgedwongen blijven.

queryDataSources(..., asTable="orders") houdt het helperresultaat op het parquet/DuckDB pad en laadt het in de lokale connection als orders. Het resultaat heeft table, rowCount, columns, metadata, artifact en lege rows.

Runtime builtin function contracts

Helpers die data, Dashbot tools of e-mailbezorging aanroepen gebruiken de access context van de execution: de huidige gebruiker, een scheduled automation on-behalf-of gebruiker, of tenant-system context voor intern materialisatiewerk. queryDataSources, askDashbot en sendEmail sturen die context downstream door; services controleren daarna opnieuw actuele permissies en forced filters. Element-code kan geen bredere context minten. Tijdens parquetrefresh-materialisatie mag de tenant-system context tenant-datasources lezen zodat Element-datasourcecode dynamische queryDataSources-calls kan uitvoeren zonder elke dependency vooraf te declareren.

Voor exacte signatures, payloadvelden, return shapes en voorbeeldcode per helper gebruik je de Runtime builtin function contract pages.

GebiedBuiltin contract pagesGebruik voor
Lokale SQLduckdbGebruik Element-local DuckDB tabellen, workspace files en table-shaped output.
Datasource accessqueryDataSources, appendDataSourceRowsLees tenant-scoped datasources met forced filters of append duurzame rows naar schrijfbare parquet/uplink datasources.
Request artifactswriteFile, readFile, listFilesSchrijf, lees en lijst files die aan de huidige Element-request zijn gekoppeld.
Tenant GCS filesuploadGcsFile, downloadGcsFile, signGcsFile, listGcsFiles, deleteGcsFileBeheer duurzame tenant files onder filestore/{tenantId}/....
AI en deliveryaskDashbot, sendEmailRoep Dashbot of notification delivery aan met behoud van de execution access context.
Runtime storegetVar, setVar, getSecretLees niet-secret configuratie, schrijf bewuste runtime variables en lees secrets alleen binnen runtime.
Live streamingemitProgress, appendRows, replaceRows, clearRowsEmit progress en live row commands voor livestream-style Element executions.
Side effectscreateNotification, createTaskReturn notification- en task-side-effect payloads vanuit Element execution.
DiagnosticstimeBlock, loggerLeg timing en gestructureerde execution logs vast zonder debug-blobs aan gebruikers te returnen.

De helpers hierboven zijn geïnjecteerde globals in de Element-runtime. De dedicated contract pages bevatten optionele import shims, voorbeeldcalls, payloadvoorbeelden, return payloads en security caveats per helper.

Lifecycle workflows

  1. Maak of update de Element draft. Behoud source, dependencies, entrypoint en metadata fields die niet bij de wijziging horen.
  2. Publish het Element en bewaar de teruggegeven version id.
  3. Draai een kleine test execution payload. Bekijk execution logs bij import-, dependency-, timeout-, secret-, variable- of result-shape fouten.
  4. Voor een Element-backed datasource maak of update je de datasource met type="element", elementId, elementVersion en elementEntrypoint="run".
  5. Voor cached parquet zet je dataFormat="parquet-remote", queue je een parquet refresh en lees je de datasource flow totdat de terminal refresh event zichtbaar is.
  6. Query de datasource en bind dashboard tables/filters alleen aan geverifieerde columns.

Veel voorkomende ongeldige payloads

  • dataFormat="parquet" op een datasource die door parquetrefresh ververst moet worden. Gebruik parquet-remote of parquet-remote-view.
  • Element datasource zonder gepubliceerde elementVersion.
  • Draft source die de ingestelde entrypoint niet definieert.
  • Hardcoded API keys, tokens of passwords in Element source. Gebruik runtime secrets.
  • Live update code die yield gebruikt voor progress. Gebruik emitProgress, appendRows, replaceRows en clearRows.
  • Live appendRows() gebruiken wanneer duurzame parquet opslag nodig is. Gebruik appendDataSourceRows() of dataSources.appendRows().
  • yield en return <value> mixen in dezelfde entrypoint.

MCP tool names

  • Runtime reference: get_element_runtime_contract, list_element_builtin_functions, get_element_builtin_function.
  • Element lifecycle: validate_element, create_element, update_element, publish_element, run_element_test, list_element_execution_logs, read_element_execution_log.
  • Runtime store: list_runtime_variables, set_runtime_variable, delete_runtime_variable, list_runtime_secrets, set_runtime_secret, delete_runtime_secret.
  • Datasource verification: validate_datasource, create_datasource, update_datasource, refresh_datasource_parquet, list_datasource_flows, read_datasource_flow, run_datasource_query.
  • Docs discovery: search_dashview_docs, resolve_dashview_doc_topic, read_dashview_doc_topic.

Backend API route references

  • GET /elements, GET /elements/{element_id}, POST /elements, PUT /elements/{element_id}.
  • POST /elements/{element_id}/publish, POST /elements/{element_id}/execute.
  • GET /elements/{element_id}/execution-logs, GET /elements/{element_id}/execution-logs/{log_id}.
  • GET /runtime-store/vars, PUT /runtime-store/vars/{variable_id}, GET /runtime-store/secrets, PUT /runtime-store/secrets/{secret_id}.
  • POST /data-sources/{datasource_id}/parquet-refresh voor cached datasource refresh.

Gebruik de MCP Swagger helpers get_backend_api_summary, search_backend_api_endpoints en get_backend_api_endpoint voor raw backend calls.

LLM-oriented voorbeelden

# Before writing Element source through MCP:
runtime = get_element_runtime_contract()
query_helper = get_element_builtin_function("queryDataSources")
secret_helper = get_element_builtin_function("getSecret")

# Before guessing docs filenames:
doc = read_dashview_doc_topic("element-runtime-builtins")

# Before binding a table/filter:
rows = run_datasource_query(
  "select * from orders_from_element limit 20",
  sources=[{"dataSourceId": "orders_from_element"}],
  strict_sources=True,
  max_rows=20
)