Skip to main content

PennyLane-Open Quantum Plugin

A PennyLane plugin for the Open Quantum quantum computing platform. Submit quantum circuits to real quantum hardware through the Open Quantum SDK.

Installation

pip install openquantum-sdk-pennylane

That's it. Installing the package automatically registers the openquantum.device with PennyLane via Python entry points — no extra imports needed. Just import pennylane as qml and use qml.device("openquantum.device", ...).

For development:

pip install openquantum-sdk-pennylane[dev]

Quick Start

import pennylane as qml

# No need to import openquantum — the device registers automatically on install.
dev = qml.device(
    "openquantum.device",
    wires=2,
    shots=1024,
    backend="ionq:aria-1",
    client_id="your_client_id",
    client_secret="your_client_secret",
)

@qml.qnode(dev)
def bell_state():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    return qml.counts()

result = bell_state()
# The device shows backend status, credit cost, and prompts for confirmation:
#   [Open Quantum] ● IonQ Aria-1 (ionq:aria-1): Online | queue: 0 job(s)
#   [Open Quantum] Batch: 1 circuit(s) × 2 credit(s) each = 2 credit(s) total
#   [Open Quantum] Proceed? [y/N] y
print(result)  # {'00': 512, '11': 512}

Configuration

Required Parameters

Parameter Description
wires Number of qubits
shots Number of measurement shots (required, no analytic mode)
backend Backend class ID or short_code (e.g., "ionq:aria-1")

Authentication

The plugin supports three authentication methods, checked in order:

  1. Pre-built OpenQuantumClient -- pass client= for full control.
  2. Bearer token -- pass token= or set OPENQUANTUM_TOKEN.
  3. Client credentials -- pass client_id= + client_secret= or set OPENQUANTUM_CLIENT_ID + OPENQUANTUM_CLIENT_SECRET.
Parameter Environment Variable Description
token OPENQUANTUM_TOKEN Bearer token
client_id OPENQUANTUM_CLIENT_ID OAuth2 client ID
client_secret OPENQUANTUM_CLIENT_SECRET OAuth2 client secret
OPENQUANTUM_SDK_KEY Path to an SDK-key JSON file ({client_id, client_secret})
organization_id OPENQUANTUM_ORGANIZATION_ID Organization UUID (optional if single org)
scheduler_url OPENQUANTUM_SCHEDULER_URL Scheduler API base, when the argument is omitted
management_url OPENQUANTUM_MANAGEMENT_URL Management API base, when the argument is omitted
keycloak_base OPENQUANTUM_KEYCLOAK_BASE Keycloak base, when the argument is omitted
realm OPENQUANTUM_KEYCLOAK_REALM Keycloak realm, when the argument is omitted

The device calls OpenQuantumClient.from_env(). Missing credentials raise AuthenticationError. The constructor parameter is client=, not scheduler=.

Cost Control and Execution Flow

Before executing circuits, the device:

  1. Checks backend status — with verbose=True, reports whether the target QPU is online and its queue depth. If the backend is unavailable, lists alternatives and asks before continuing unless auto_confirm=True.
  2. Shows credit cost — prepares the first circuit to get a real quote. The cost is printed when verbose=True, and whenever the confirmation prompt is shown.
  3. Prompts for confirmation (terminal only) — asks Proceed? [y/N]. In Jupyter notebooks, execution proceeds immediately (use auto_confirm=True or interrupt the kernel to cancel).
  4. Live status updates — with verbose=True, shows a spinner during execution. While the job is pending, you can interrupt (Ctrl+C or Jupyter stop button) to cancel it on the platform. Once the job is queued, it can no longer be cancelled. The wait is bounded by job_timeout_seconds.
Parameter Default Description
auto_confirm False Skip the interactive cost confirmation prompt (terminal) and backend-unavailable warnings.
verbose False Print submission progress and the credit cost. Same default on every plugin.
# Default: prints the cost and prompts in the terminal
dev = qml.device("openquantum.device", wires=2, shots=1024, backend="ionq:aria-1", ...)

# Skip prompts and stay quiet
dev = qml.device("openquantum.device", wires=2, shots=1024, backend="ionq:aria-1", auto_confirm=True, ...)

# Skip prompts, print progress and credit cost
dev = qml.device("openquantum.device", wires=2, shots=1024, backend="ionq:aria-1", auto_confirm=True, verbose=True, ...)

# Check cumulative credits spent at any time
print(dev.total_credits_used)

Example output with verbose=True (the status lines are omitted when verbose is left at False; the cost line and prompt still appear unless auto_confirm=True):

[Open Quantum] ● IonQ Aria-1 (ionq:aria-1): Online | queue: 2 job(s)
[Open Quantum] Batch: 1 circuit(s) × 2 credit(s) each = 2 credit(s) total
[Open Quantum] Proceed? [y/N] y
  [1/1] ⠹ Pending... (interrupt to cancel) (3s)
  [1/1] Queued — can no longer be cancelled.
  [1/1] ⠸ Running... (12s)
[Open Quantum] Batch complete: 2 credits used in 18s (session total: 2)

Multi-circuit batch with verbose=True:

[Open Quantum] Batch: 40 circuit(s) × 2 credit(s) each = 80 credit(s) total
[Open Quantum] Proceed? [y/N] y
  [1/40] done (2/80 credits)
  [2/40] done (4/80 credits)
  ...
[Open Quantum] Batch complete: 80 credits used in 245s (session total: 80)

Execution Plans & Queue Priority

Control cost and scheduling with execution_plan and queue_priority:

dev = qml.device(
    "openquantum.device",
    wires=2,
    shots=1024,
    backend="ionq:aria-1",
    execution_plan="private",    # "auto", "public", or "private"
    queue_priority="priority",   # "auto", "standard", "priority", or "instant"
    ...
)
Parameter Values Default Description
execution_plan "auto", "public", "private", enum, or UUID "auto" "auto" selects the cheapest available plan. "private" uses dedicated resources at higher cost.
queue_priority "auto", "standard", "priority", "instant", enum, or UUID "auto" "auto" selects the cheapest priority. Higher priorities cost more but reduce queue wait time.

Job Subcategory

The job_subcategory_id parameter classifies the type of workload you're running. It defaults to "oth:oth" (Other) but you should set it to the most specific subcategory that matches your use case. See the core SDK README for the full list of subcategory short codes.

dev = qml.device(
    "openquantum.device",
    wires=2,
    shots=1024,
    backend="ionq:aria-1",
    job_subcategory_id="ml:qcl",  # Quantum Classification
    ...
)

Other Optional Parameters

Parameter Default Description
scheduler_url https://scheduler.openquantum.com Scheduler API base URL
management_url https://management.openquantum.com Management API base URL
keycloak_base https://id.openquantum.com Keycloak auth base URL
realm "platform" Keycloak realm
job_timeout_seconds 86400 Max wait for job completion

Supported Operations

Gates

PauliX, PauliY, PauliZ, Hadamard, CNOT, CZ, SWAP, RX, RY, RZ, PhaseShift, S, T, SX, Toffoli, CSWAP, CRX, CRY, CRZ, Identity

Measurements

  • qml.counts() - Measurement counts
  • qml.expval() - Expectation values
  • qml.var() - Variance
  • qml.probs() - Probabilities
  • qml.sample() - Samples

All measurements require finite shots.

Examples

Expectation Values

@qml.qnode(dev)
def circuit(x):
    qml.RX(x, wires=0)
    qml.Hadamard(wires=1)
    qml.CNOT(wires=[0, 1])
    return qml.expval(qml.PauliZ(0))

result = circuit(0.543)

VQE Workflow

# Use auto_confirm=True for iterative algorithms to avoid
# being prompted on every optimization step.
dev = qml.device("openquantum.device", wires=2, shots=4096,
                  backend="ionq:aria-1", auto_confirm=True, ...)

@qml.qnode(dev)
def cost_fn(params):
    qml.RY(params[0], wires=0)
    qml.RY(params[1], wires=1)
    qml.CNOT(wires=[0, 1])
    return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))

opt = qml.GradientDescentOptimizer(stepsize=0.4)
params = np.array([0.5, 0.1])
for _ in range(100):
    params = opt.step(cost_fn, params)

# Check total credits consumed
print(f"Total credits used: {dev.total_credits_used}")

Device Features

The PennyLane device loads the backend's full constraint_data (including the features array). This enables:

  • Early, client-side rejection of constructs the device does not advertise (e.g. reset, barrier, mid-circuit measurement patterns) during qml.QNode execution / device.preprocess().
  • The decompose step in preprocess is driven by the device's supported gate set (from native_ops / supported_ops).
  • You can query features at runtime:
dev = qml.device("openquantum.device", wires=4, shots=1000, backend="iqm:emerald", ...)
print(dev.features)
print(dev.allows_reset())                 # False for most real QPUs today
print(dev.allows_mid_circuit_measure())
print(dev.supports_feature("dynamic_circuits"))
print(dev.allows_barriers())

The platform precompilers (in the worker) perform the definitive validation using the same feature list and will produce clear errors with source locations if something slips through.

See sdk/docs/device-features.md for the canonical list and sdk/docs/capabilities.md for the schema.

Comparison with Qiskit Plugin

Feature PennyLane Qiskit
Execution plan execution_plan= on device execution_plan= on create_sampler() / create_estimator() / config dict
Queue priority queue_priority= on device queue_priority= on create_sampler() / create_estimator() / config dict
Job subcategory job_subcategory_id= (default "oth:oth") job_subcategory_id= (default "oth:oth")
Shots Required, no default Default 100 (sampler) / 1024 (backend)
Cost confirmation Interactive prompt (auto_confirm=False) No prompt (submits immediately)
Backend status check Automatic pre-flight check Not built-in
Interrupt handling Ctrl+C cancels queued jobs Not built-in
Auth Token or client credentials (env vars or constructor) Token, client credentials, or saved accounts with keyring
Credit tracking dev.total_credits_used Not built-in
QASM format QASM 3.0 (automatic) "qasm2" or "qasm3" (configurable)

License

Apache License 2.0

Metadata

Release files for openquantum-sdk-pennylane 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openquantum-sdk-pennylane 1.0.0
File Size Uploaded Provenance Actions
openquantum_sdk_pennylane-1.0.0.tar.gz 22.9 kB Without provenance Details for openquantum_sdk_pennylane-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for openquantum-sdk-pennylane 1.0.0
File Interpreter ABI Platform Actions
openquantum_sdk_pennylane-1.0.0-py3-none-any.whl Python 3 none any Details for openquantum_sdk_pennylane-1.0.0-py3-none-any.whl

Total release size: 41.4 kB

Release files / openquantum_sdk_pennylane-1.0.0.tar.gz

Download URL openquantum_sdk_pennylane-1.0.0.tar.gz
Size 22.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f9f9110b2643bb79a3c750402891e1ee26ca9bdf8bc047fd6139616da4ee30c7
BLAKE2b-256 checksum
How to use checksums
95ee3b3465bd46722d1480ee526198f3ee0c824328488cfeca1654be5b321bba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / openquantum_sdk_pennylane-1.0.0-py3-none-any.whl

Download URL openquantum_sdk_pennylane-1.0.0-py3-none-any.whl
Size 18.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bdc3c667f6d010bd96ebbf54e094a73cacc6d544f51c05aea12e614a3c41f3b6
BLAKE2b-256 checksum
How to use checksums
53356c1067232a708d54cef32a43d5e9b158602599d6941c11cc407f20f16c07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for openquantum-sdk-pennylane 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page