Skip to main content

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.

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%)

Release history: CHANGELOG.md.

Develop

uv sync
uv run pytest

TDD discipline: every change starts with a failing test.

License

Apache 2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qbron-0.1.0a1.tar.gz (23.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qbron-0.1.0a1-py3-none-any.whl (31.9 kB view details)

Uploaded Python 3

File details

Details for the file qbron-0.1.0a1.tar.gz.

File metadata

  • Download URL: qbron-0.1.0a1.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

Hashes for qbron-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 98adf527a5155ce724ab11ee12e784b05f40a57b1746c4eda58c2feae7c0915a
MD5 513e3e21e9f9e033a015a2cf758b3748
BLAKE2b-256 b9e6f2abda74d259d3be4758808ef4de66f49d942f205ccf915011ea3556f287

See more details on using hashes here.

Provenance

The following attestation bundles were made for qbron-0.1.0a1.tar.gz:

Publisher: publish-to-pypi.yaml on qbron/qbron

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qbron-0.1.0a1-py3-none-any.whl.

File metadata

  • Download URL: qbron-0.1.0a1-py3-none-any.whl
  • Upload date:
  • Size: 31.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qbron-0.1.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 638fdde2d0746ed8392894f3c1058340e96aec59fcde87ac131c417e259edb47
MD5 2a9ce0a63ce4b791d88a34761c30c641
BLAKE2b-256 c19779b155b26855570fd0fad6bb9bfc127e80008ae3550b50585d58ff28e813

See more details on using hashes here.

Provenance

The following attestation bundles were made for qbron-0.1.0a1-py3-none-any.whl:

Publisher: publish-to-pypi.yaml on qbron/qbron

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page