Livebook Smart Cell that emits a %Qx.Hardware.Config{} binding
(qx) for downstream cells to pipe circuits through.
Registered automatically when :kino_qx is loaded — appears in
Livebook's "+ Smart" menu as "Qx Credentials" alongside the
existing "Qx Snippet" cell.
Usage
In a notebook:
# Cell 1: this Smart Cell — fill in URL/region/backend, click Connect.
# It emits:
qx = %Qx.Hardware.Config{
portal_url: "https://test.qxquantum.com",
portal_token: System.fetch_env!("LB_PORTAL_TOKEN"),
ibm_api_key: System.fetch_env!("LB_IBM_API_KEY"),
ibm_crn: System.fetch_env!("LB_IBM_CRN"),
ibm_region: "us-south",
backend: "ibm_brisbane",
optimization_level: 1,
shots: 4096
}
# Cell 2: regular Elixir
circuit
|> Kino.Qx.run!(qx)
|> Qx.Draw.plot_counts(title: "Bell state")Privacy invariant
This cell never accepts tokens into its UI. The three secrets live in Livebook secrets under these fixed names:
LB_PORTAL_TOKEN— qxportalqx_live_…bearerLB_IBM_API_KEY— IBM Cloud API keyLB_IBM_CRN— IBM Service-CRN
Connect reads them via System.fetch_env!/1; to_source/1 emits
code that does the same. Tokens never appear in cell state, never
enter the .livemd file. Sharing a notebook does not leak any
credential — the recipient must define their own secrets.
See the Livebook docs for how to add session/hub secrets: https://hexdocs.pm/livebook/secrets.html
Persisted attrs
Written into the .livemd file (none are secret):
portal_base_url— qxportal URL (defaulthttps://test.qxquantum.com)ibm_region—"us-south"or"eu-de"last_backend_name— IBM backend chosenoptimization_level— 0..3, default 1shots— 1..100_000, default 4096
Iron Law compliance
- #7 — IBM job statuses come off the wire upstream in
Qx.Hardware.Ibmand are matched against an allowlist there; this cell never coins atoms from network responses. - #8 — every
handle_event/3clause validates input shape: region in["us-south", "eu-de"]; optimization_level integer in 0..3; shots integer in 1..100_000; backend name appears in the cachedbackends_list;portal_base_urlmatches the host allowlist. - #11 — no long-lived processes. The Connect task is
short-lived (auth + list backends, then
send/2the result and exit). It is unlinked (Task.start/1) so ado_connect/1raise can't wipe cell state; orphan risk is nil because the task self-terminates after onesend/2.