Skip to main content
Version: Next

Scripting

QUBIQ exposes one API surface, system, in three execution contexts. The same call reads identically in Python and JavaScript, so a script moves between contexts without being rewritten.

The three contexts​

ContextLanguageRuns onUse for
Pipeline PythonPythonThe Python workerTransformations inside a dataflow
Gateway scriptsPythonThe gateway, server-sideTransactions, long work, anything a browser must not own
Client scriptsJavaScriptThe operator's browserScreen interaction, validation, UI logic

Choosing​

A decision chart: work inside a dataflow goes in a pipeline Python node; work triggered by a screen goes to a gateway script if it touches a database or takes a while, otherwise to a client script.A decision chart: work inside a dataflow goes in a pipeline Python node; work triggered by a screen goes to a gateway script if it touches a database or takes a while, otherwise to a client script.
Two questions decide where a piece of logic belongs.

Two rules cover nearly every case:

  1. Anything transactional belongs on the gateway. A browser disconnect must not be able to strand an open transaction holding locks.
  2. Anything that must not be lost belongs in a pipeline. Pipeline writes are covered by store-and-forward; script writes are not.

The system API​

NamespacePurpose
system.tagRead and write namespace tags
system.dbSQL, named queries, stored procedures, transactions
system.histHistorian trends, statistics and point-in-time values
system.varsGateway variables — per project, or global
system.filesRead and write files in the workspace uploads folder
system.messageSend on the message bus to pipelines and screens, or ask and wait for a reply 1.0.8
system.scriptRun a Gateway entry point server-side — from a browser, or from a pipeline Python node 1.0.8

Full signatures, per-method detail and worked examples: System API reference.

And context, in the browser​

A browser script gets a second global, context — the view, its components, the live tag values already on screen, the operator's session, and the shell around the view (panels, toasts, popovers).

The division is worth learning early: system.* crosses the wire and is permission-gated; context.* does not and is not. A read of context.tag["..."] costs nothing because the screen already has the value; await system.tag.read("...") is a round trip that asks the server.

→ Context API reference

The same code, both languages​

Python
result = system.tag.read("Line1/Filler/Motor1/Speed")
if result["quality"] == "Good" and result["value"] > 2800:
system.tag.write("Line1/Filler/Motor1/SpeedSetpoint", 2500)
JavaScript
const result = await system.tag.read("Line1/Filler/Motor1/Speed");
if (result.quality === "Good" && result.value > 2800) {
await system.tag.write("Line1/Filler/Motor1/SpeedSetpoint", 2500);
}

The method names are camelCase in both languages — deliberately, so a script reads the same wherever it runs.

Always check quality​

r = system.tag.read("Line1/Tank1/Level")
if r["quality"] != "Good":
return None # do not act on an untrustworthy value

A Bad-quality read still returns a value — the last known one. Acting on it is how a dead sensor drives a live process. This is the single most important habit in QUBIQ scripting.

Batch, do not loop​

# ❌ N round trips
values = [system.tag.read(p) for p in paths]

# ✅ one
values = system.tag.readAll(paths)

The same applies to database work: one query returning many rows beats many queries returning one.

The sandbox​

Scripts run in a restricted environment. The standard set (system, math, json, datetime) is available; administrators can install additional Python packages, which land in a managed directory on the worker's path.

→ The script sandbox

The editor​

The Python editor lints as you type, so syntax errors surface while you are writing rather than when the pipeline fires at 03:00.

The Problems panel New in 1.0.6 lists what the linter found — message, severity, rule id and Ln 4, Col 7 — and clicking a row goes there. The footer used to show a bare count, which told you there was a problem and then declined to say what; the only route to the actual fault was to notice a squiggle somewhere in a scrolled file and hover it. Every editor's diagnostics arrive through the same panel, whether they came from the Python linter, TypeScript or CSS.

One font size, everywhere. New in 1.0.6 The − / + control sets the size for every code editor in the Designer — project scripts, event and binding scripts, named queries, CSS and the pipeline node editor — and it persists, so turning it up to read a long script does not have to be done again in the next panel. The AI chat and the assistant panel have their own, scoped to the message text so the header and controls stay put.

Changed in 1.0.8 The code editors, the AI Assistant panel and the AI chat widget default to 14 px (it was 16). On upgrade a stored size of 16 becomes 14 — the old default was saved for everyone, so it cannot be told apart from a choice — and any other size is kept.

Security​

  • Scripts run with the gateway's authority — a script can read any tag and any connection it names. Grant script-authoring permissions accordingly.
  • Prefer named queries over string-built SQL. Where inline SQL is unavoidable, always parameterise.
  • Do not put credentials in scripts or in variables. Use a connection's credential storage.
  • Consequential actions are recorded in the audit journal.

In this section​

PageContents
System API referenceEvery namespace, method and signature
Python nodesScripting inside a pipeline
Gateway scriptsServer-side entry points
Client scriptsBrowser-side screen logic
The script sandboxWhat is available, and how to extend it