PennyLane Python SDK for Open Quantum
Project description
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:
- Pre-built SchedulerClient -- pass
scheduler=for full control. - Bearer token -- pass
token=or setOPENQUANTUM_TOKEN. - Client credentials -- pass
client_id=+client_secret=or setOPENQUANTUM_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 |
organization_id |
OPENQUANTUM_ORGANIZATION_ID |
Organization UUID (optional if single org) |
Cost Control and Execution Flow
Before executing circuits, the device:
- Checks backend status — reports whether the target QPU is online, its queue depth, and lists online alternatives if it is offline or not accepting jobs.
- Shows credit cost — prepares the first circuit to get a real quote, then displays the per-circuit and total cost.
- Prompts for confirmation (terminal only) — asks
Proceed? [y/N]. In Jupyter notebooks, execution proceeds immediately (useauto_confirm=Trueor interrupt the kernel to cancel). - Live status updates — shows a spinner with job status 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.
| Parameter | Default | Description |
|---|---|---|
auto_confirm |
False |
Skip the interactive cost confirmation prompt (terminal) and backend-unavailable warnings. Credits used are still printed to stdout. |
# Default: shows cost, prompts in terminal
dev = qml.device("openquantum.device", wires=2, shots=1024, backend="ionq:aria-1", ...)
# Skip prompts (still prints cost and status)
dev = qml.device("openquantum.device", wires=2, shots=1024, backend="ionq:aria-1", auto_confirm=True, ...)
# Check cumulative credits spent at any time
print(dev.total_credits_used)
Example output during execution:
[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:
[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" |
"auto" |
"auto" selects the cheapest plan (public). "private" uses dedicated resources at higher cost. |
queue_priority |
"auto", "standard", "priority", "instant" |
"auto" |
"auto" selects the cheapest priority (standard). 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 countsqml.expval()- Expectation valuesqml.var()- Varianceqml.probs()- Probabilitiesqml.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) duringqml.QNodeexecution /device.preprocess(). - The
decomposestep in preprocess is driven by the device's supported gate set (fromnative_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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openquantum_sdk_pennylane-0.1.7.tar.gz.
File metadata
- Download URL: openquantum_sdk_pennylane-0.1.7.tar.gz
- Upload date:
- Size: 20.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff7b0f88427be87b10f564689138bf61698854474d73a5dcee6e45ef1f4a99a1
|
|
| MD5 |
d442d02e133b13a4f2d34c708dbfa5b3
|
|
| BLAKE2b-256 |
8047c21fad336d5d6780028931379a1682a6476319cc7787d25f24fbee446529
|
File details
Details for the file openquantum_sdk_pennylane-0.1.7-py3-none-any.whl.
File metadata
- Download URL: openquantum_sdk_pennylane-0.1.7-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23b3208a31ed2f7c5884d078842ce06876d71d32413d35a649cf67245c8dae95
|
|
| MD5 |
f2d0f8e20f0457e38a4346650cd66a68
|
|
| BLAKE2b-256 |
463dc2d4d793f37c564b293475f889c7dd936e4b6877f0c3b1bd12177c11f342
|