Livebook Smart Cells + pipeline functions for running quantum circuits on real IBM hardware via the Qx Portal.

Two cells ship in this package:

  1. Qx Snippet — browse the snippets you've saved on the portal, pick one from a dropdown, and inject the OpenQASM 3.0 (or converted Elixir/Qx) source straight into a notebook cell.
  2. Qx Credentials (new in 0.2.0) — collects portal URL, region, backend, optimization level, and shots; emits a %Qx.Hardware.Config{} binding (qx) that downstream cells pipe circuits through Kino.Qx.run!/2.

End-to-end pipeline:

circuit
|> Kino.Qx.run!(qx)
|> Qx.Draw.plot_counts(title: "Bell state")

Status

v0.2.0 is a breaking architectural reset. The previous Kino.Qx.TranspileCell (paste-QASM + Submit button + inline result rendering) is replaced by Kino.Qx.CredentialsCell + a Kino.Qx.run!/2 pipeline function. The transpile / submit / poll core moved upstream into Qx.Hardware in the :qx library (0.7.0); kino_qx becomes a thin UX layer that adds a live Kino.Frame status panel.

The portal-side JSON API is locked at /api/v1 — see the API reference. The IBM Quantum REST API is documented at quantum.cloud.ibm.com.

Installation

In a Livebook setup cell:

Mix.install([
  {:kino_qx, "~> 0.2"},
  {:qx, "~> 0.7"}
])

Click + Smart at the bottom of any notebook cell. You'll see both cells in the menu — pick the one you need.

Cell 1 — Qx Snippet (unchanged from 0.1)

Needs:

  1. A qx_live_* portal token. Dashboard → API Keys → Generate Key.
  2. Portal URL (defaults to https://qxportal.dev).

The token is stored only in transient cell state and never serialized into the .livemd file.

Cell 2 — Qx Credentials + Kino.Qx.run!/2

Livebook secrets (one-time per notebook)

The cell never asks for tokens directly. It reads three Livebook secrets at Connect / run time:

Secret nameWhat it is
LB_PORTAL_TOKENqxportal qx_live_… bearer (Dashboard → API Keys → Generate Key)
LB_IBM_API_KEYIBM Cloud API key (https://quantum-computing.ibm.com/ → Account)
LB_IBM_CRNIBM Service-CRN (crn:v1:bluemix:public:quantum:…)

Add each via the lock icon in Livebook's left sidebar before clicking Connect. The .livemd file never carries any token — sharing a notebook leaks nothing.

Cell UI

  • Portal URL — defaults to https://test.qxquantum.com. Validated against a host allowlist (*.qxquantum.com over https; localhost/127.0.0.1 over http for dev) so a malicious shared notebook cannot redirect your token.
  • Regionus-south (default) or eu-de. Must match the region encoded in your CRN.
  • Connect — reads the three secrets, validates auth, populates the backend dropdown.
  • Backend / Optimization / Shots — chosen per cell run.

Pipeline

circuit =
  Qx.create_circuit(2, 2)
  |> Qx.h(0)
  |> Qx.cx(0, 1)
  |> Qx.measure(0, 0)
  |> Qx.measure(1, 1)

circuit
|> Kino.Qx.run!(qx)
|> Qx.Draw.plot_counts(title: "Bell state")

A live Kino.Frame status panel renders above the result while the job moves through transpile → submit → queued → running → done. If you click Livebook's "Stop" button mid-run, a best-effort Qx.Hardware.cancel/3 fires for the in-flight job.

Kino.Qx.run!/2 raises Kino.Qx.RunError on failure (pipe-friendly). The tuple-returning Kino.Qx.run/2,3 is also available for production-style with chains.

Outside Livebook

The hardware-execution core lives in Qx.Hardware. CLI scripts, Phoenix apps, and OTP services can run circuits without a Livebook runtime:

config = %Qx.Hardware.Config{
  portal_url: "https://test.qxquantum.com",
  portal_token: System.fetch_env!("PORTAL_TOKEN"),
  ibm_api_key: System.fetch_env!("IBM_API_KEY"),
  ibm_crn: System.fetch_env!("IBM_CRN"),
  ibm_region: "us-south",
  backend: "ibm_brisbane"
}

{:ok, result} = Qx.Hardware.run(circuit, config)

Kino.Qx.run/2,3 adds the status frame and cancel watcher around the same Qx.Hardware.run/3 call.

What's NOT in v1

  • Estimator primitive — Sampler only (Estimator deferred; base64 tensor decoding deserves its own iteration).
  • Multi-circuit batches — one circuit per run!/2 call.
  • OpenQASM 2.0 input — qxportal accepts 3.0 only; convert client-side first.

Compatibility

kino_qxqxKinoElixir
0.2.x~> 0.7~> 0.19>= 1.17
0.1.xn/a~> 0.19>= 1.17

Troubleshooting

Qx Snippet

SymptomLikely cause
unauthorized (401)Token is wrong, revoked, or for a different portal
Empty dropdownYou haven't saved any snippets to the portal yet
rate_limited (429)More than 60 requests per minute on this key — wait + retry
Network timeoutWrong portal URL, or the portal is unreachable from this host

Qx Credentials + Kino.Qx.run!

SymptomLikely cause
Missing Livebook secret LB_PORTAL_TOKENAdd the secret via the lock icon in Livebook's sidebar
Auth rejected (401) from ConnectSecret values wrong, or IBM region doesn't match the CRN
Qx.Hardware.NoMeasurementsErrorCircuit has no Qx.measure/3 calls — Sampler V2 requires them
Portal rejected the QASM (422)OpenQASM 2.0 input or syntax error; convert to 3.0
Portal transpile failed (502)Circuit too wide for the backend; try a smaller backend or optimization_level: 0
Kino.Qx.InterruptedYou clicked Livebook's Stop button mid-run; cancel was issued
Cell stuck on "queued"IBM queue can be very long; the pipeline polls until terminal status
Connect succeeds but no backendsYour IBM instance has no backends provisioned for this region
Portal URL must be https://…The URL is not on the allowlist (*.qxquantum.com over https)

License

Apache 2.0.