Open-source SDK for running quantum workloads across any QPU backend.
Project description
Qbron
Unified Python SDK for quantum backends. Write your circuit once, route it to any QPU.
qbron is an open-source SDK that gives developers one API across IBM Quantum, IQM Resonance, AWS Braket, Azure Quantum, and local simulators — with cost transparency, smart routing, and EU data sovereignty. Apache 2.0.
The name is Swedish: bron = bridge.
Status: early development. See
CLAUDE.mdfor the architecture diagram and the build-order scoreboard.
Install
pip install qbron # or: uv add qbron
Requires Python 3.11+.
Quick start
Python
from qbron.circuit import Circuit
from qbron.simulator import LocalSimulator
# Bell state on 2 qubits
bell = Circuit(num_qubits=2).h(0).cx(0, 1)
result = LocalSimulator(seed=42).run(bell, shots=1000)
print(result.counts)
# {'00': 480, '11': 520} # entangled — never '01' or '10'
CLI
cat > bell.qasm <<'EOF'
OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
h q[0];
cx q[0], q[1];
EOF
qbron run bell.qasm --shots 1000 --seed 42
# 00: 480
# 11: 520
Pick a backend:
qbron run bell.qasm --backend=local # pure-Python statevector (default)
qbron run bell.qasm --backend=mock # priced fake remote (SEK)
qbron run bell.qasm --backend=aer # Qiskit Aer simulator
qbron run bell.qasm --backend=ibm # IBM Quantum (QBRON_IBM_TOKEN)
qbron run bell.qasm --backend=braket-local # AWS Braket offline simulator
qbron run bell.qasm --backend=braket # AWS Braket (AWS creds)
qbron run bell.qasm --backend=azure # Azure Quantum (QBRON_AZURE_*)
qbron run bell.qasm --backend=auto # cheapest compatible
Explicit measurement
# Measure only qubit 0; output bitstrings are 1 char wide.
half_bell = Circuit(num_qubits=2).h(0).cx(0, 1).measure(0)
LocalSimulator(seed=42).run(half_bell, shots=100).counts
# {'0': 48, '1': 52}
If a circuit has no Measure gates, every qubit is implicitly measured at the end (matches what most cloud APIs return).
OpenQASM 3.0 round-trip
from qbron.circuit import Circuit
bell = Circuit(num_qubits=2).h(0).cx(0, 1)
qasm = bell.to_qasm()
assert Circuit.from_qasm(qasm) == bell
The emitter is validated against the official openqasm3 parser, and the round-trip is property-tested with Hypothesis.
Cost estimation
from qbron.mock_backend import MockRemoteBackend
backend = MockRemoteBackend()
cost = backend.estimate_cost(bell, shots=1000)
print(cost)
# Cost(currency='SEK', amount=10.0)
Smart routing — --backend=auto
from qbron.routing import route
from qbron.simulator import LocalSimulator
from qbron.mock_backend import MockRemoteBackend
# Pick the cheapest backend that can run the circuit. Costs in
# different currencies are normalised before comparison.
backend = route(
bell, shots=1000,
backends=[MockRemoteBackend(), LocalSimulator()],
target_currency="USD",
)
result = backend.run(bell, shots=1000)
Result caching
from qbron.caching import CachedBackend
from qbron.mock_backend import MockRemoteBackend
backend = CachedBackend(MockRemoteBackend())
backend.run(bell, shots=1000) # cache miss — actually runs
backend.run(bell, shots=1000) # cache hit — instant, free
Error mitigation
from qbron.mitigation import (
ReadoutMitigatedBackend, ZNEBackend, calibrate_readout,
)
# Readout correction — calibrate once, apply to every run.
calibration = calibrate_readout(backend, num_qubits=2, shots=2000)
mitigated = ReadoutMitigatedBackend(backend, calibration)
# Zero-noise extrapolation — runs at multiple noise scales.
zne = ZNEBackend(backend, scale_factors=(1, 3, 5))
Hybrid optimisation (VQE-style)
import math
from qbron.circuit import Circuit
from qbron.hybrid import gradient_descent
from qbron.simulator import LocalSimulator
backend = LocalSimulator(seed=42)
def expectation_z(params):
# ⟨Z⟩ on RY(θ)|0⟩ = cos(θ); minimum at θ = π.
ansatz = Circuit(num_qubits=1).ry(0, params[0])
counts = backend.run(ansatz, shots=4000).counts
return (counts.get("0", 0) - counts.get("1", 0)) / 4000
result = gradient_descent(expectation_z, initial_params=[0.5])
print(result.params, result.value) # ≈ [3.14], ≈ -1.0
OpenTelemetry tracing
from qbron.observability import TracedBackend
# Each run() emits a `qbron.backend.run` span with circuit shape,
# shot count, distinct outcomes, and exception info on failure.
traced = TracedBackend(backend)
traced.run(bell, shots=1000)
Run on real IBM hardware
from qbron.ibm_backend import IBMBackend
# Reads QBRON_IBM_TOKEN from the environment.
backend = IBMBackend.from_env("ibm_brisbane")
result = backend.run(bell, shots=1000)
For tests or local experiments without a real account, swap in a fake:
from qiskit_ibm_runtime.fake_provider import FakeBrisbane
from qbron.ibm_backend import IBMBackend
backend = IBMBackend(FakeBrisbane()) # IBM-shaped, runs locally
result = backend.run(bell, shots=1000)
QiskitBackend accepts any Qiskit BackendV2, so AerSimulator, third-party Qiskit-compatible providers, and custom noise models all work:
from qiskit_aer import AerSimulator
from qbron.qiskit_backend import QiskitBackend
result = QiskitBackend(AerSimulator()).run(bell, shots=1000)
Run on AWS Braket and Azure Quantum
from qbron.braket_backend import BraketBackend
from qbron.azure_backend import AzureBackend
# AWS Braket — uses standard AWS env vars (AWS_ACCESS_KEY_ID etc.)
braket = BraketBackend.from_env(
"arn:aws:braket:::device/quantum-simulator/amazon/sv1"
)
# Azure Quantum — needs QBRON_AZURE_SUBSCRIPTION_ID, RESOURCE_GROUP,
# WORKSPACE_NAME, LOCATION
azure = AzureBackend.from_env("ionq.simulator")
For local Braket experimentation without AWS:
from qiskit_braket_provider import BraketLocalBackend
from qbron.braket_backend import BraketBackend
result = BraketBackend(BraketLocalBackend()).run(bell, shots=1000)
Supported
| Gates | H · X · Y · Z · S · S† · T · T† · CX · RX(θ) · RY(θ) · RZ(θ) · Measure |
| Backends | LocalSimulator · MockRemoteBackend · QiskitBackend · IBMBackend · BraketBackend · AzureBackend · IQMBackend |
| Format | OpenQASM 3.0 in/out (validated by the official parser) |
| Correctness | Cross-validated against Qiskit Aer (TVD < 5%) |
Roadmap and architecture: CLAUDE.md.
Develop
uv sync
uv run pytest
TDD discipline: every change starts with a failing test.
License
Apache 2.0 — see LICENSE.
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 qbron-0.1.0.dev0.tar.gz.
File metadata
- Download URL: qbron-0.1.0.dev0.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f100fdc5972e83c15cc99a949cb173ce3754805275e9cb5038da6f24155232b1
|
|
| MD5 |
925f9ebb26c34abde752df2ac5f4fc9b
|
|
| BLAKE2b-256 |
9dfa02beb5763d9fd1f4036c51f78b560ea49112be0625045d116cb2a1861f62
|
Provenance
The following attestation bundles were made for qbron-0.1.0.dev0.tar.gz:
Publisher:
publish-to-pypi.yaml on qbron/qbron
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qbron-0.1.0.dev0.tar.gz -
Subject digest:
f100fdc5972e83c15cc99a949cb173ce3754805275e9cb5038da6f24155232b1 - Sigstore transparency entry: 1436108758
- Sigstore integration time:
-
Permalink:
qbron/qbron@465c2c1ecba1db079575699924b0de8e61b31fb6 -
Branch / Tag:
refs/tags/v0.1.0dev0 - Owner: https://github.com/qbron
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yaml@465c2c1ecba1db079575699924b0de8e61b31fb6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file qbron-0.1.0.dev0-py3-none-any.whl.
File metadata
- Download URL: qbron-0.1.0.dev0-py3-none-any.whl
- Upload date:
- Size: 32.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf42b4738fca76c098e17f924c7258e67aa5cd80204a53ba070d6174e7615343
|
|
| MD5 |
e9ea1f646756c4775bc41fa891c64ec5
|
|
| BLAKE2b-256 |
356cee8e7c4dbff3d465fa0ab04a6680817f2eb90dfef2eaa6fd7705a9409331
|
Provenance
The following attestation bundles were made for qbron-0.1.0.dev0-py3-none-any.whl:
Publisher:
publish-to-pypi.yaml on qbron/qbron
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qbron-0.1.0.dev0-py3-none-any.whl -
Subject digest:
cf42b4738fca76c098e17f924c7258e67aa5cd80204a53ba070d6174e7615343 - Sigstore transparency entry: 1436108760
- Sigstore integration time:
-
Permalink:
qbron/qbron@465c2c1ecba1db079575699924b0de8e61b31fb6 -
Branch / Tag:
refs/tags/v0.1.0dev0 - Owner: https://github.com/qbron
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yaml@465c2c1ecba1db079575699924b0de8e61b31fb6 -
Trigger Event:
push
-
Statement type: