niobium — the Qubitra Python SDK
The Python client for the Qubitra platform. Codename niobium; it installs as
qubitra-sdk and imports as qubitra (ADR-0041 D1).
The SDK speaks q-platform vocabulary — Backends, Jobs, Offerings — and talks to the
Qubitra API's public /v1 surface. Which backend a Job actually lands on, and the
supply chain behind it, is the platform's business: the SDK never names a vendor.
Install
pip install qubitra-sdk
Inside this repo it is a uv workspace member, so uv sync at the root installs it
editable and no publish step is involved.
Quickstart
from qubitra import QubitraClient
BELL = (
'OPENQASM 3.0; include "stdgates.inc"; qubit[2] q; bit[2] c; '
"h q[0]; cx q[0], q[1]; c = measure q;"
)
with QubitraClient() as client:
for backend in client.backends.list():
print(backend.id, backend.qubit_count, backend.supported_formats)
job = client.jobs.submit(
backend_id="sim-statevector-26q",
circuit=BELL,
shots=1024,
name="bell-pair",
)
job = client.jobs.wait(job.id, timeout=600)
if job.status.is_terminal and job.error:
raise SystemExit(f"job {job.id} failed: {job.error}")
print(client.jobs.result(job.id).counts) # {"00": 512, "11": 512}
include "stdgates.inc"; is required: OpenQASM 3 defines no gates of its own, so h and
cx are undefined without it.
Runnable versions sit in examples/: submit_bell_pair.py is the whole path,
list_backends.py is the read-only smoke test, estimate_expectation.py submits an
estimator PUB, and parameter_sweep.py sweeps an input declaration. All take their key
from the environment:
QUBITRA_API_KEY=qpk_... uv run pkg/niobium/examples/submit_bell_pair.py
Against a local stack (mise run dev:qplat), add QUBITRA_API_URL=http://localhost:8080 and
mint a key on the console's API keys page.
Configuration
| Variable | Default | Meaning |
|---|---|---|
QUBITRA_API_KEY |
— | API key (qpk_…), required. Resolves to your organization. |
QUBITRA_API_URL |
http://localhost:8080 |
The Qubitra deployment to reach. |
Both are also constructor arguments — QubitraClient(api_key=…, api_url=…) — which
take precedence over the environment.
Surface
| Call | What it does |
|---|---|
client.backends.list() / .get(id) |
The backends available to you, and one by id. |
client.jobs.submit(...) |
Submit one circuit as a job of a single PUB; returns a Job immediately. |
client.jobs.run(backend_id=…, pubs=[…]) |
Submit an ordered list of PUBs as one job. |
client.jobs.list() |
Your organization's jobs, newest first. |
client.jobs.get(id) / .result(id) / .cancel(id) |
Read status, fetch results, cancel. |
client.jobs.wait(id) |
Poll until the Job reaches a terminal status. |
client.sessions.create(...) / .list() / .get(id) / .close(id) |
Correlate a run and bound its budget. |
client.marketplace.offerings() |
The marketplace catalogue. |
A job carries an ordered list of PUBs (ADR-0049 D3) — a Pub is a circuit plus
optional observables, parameter_values rows and shots. JobResult.pubs comes back
index-aligned with the submission, each entry one of CountsResult,
ProbabilitiesResult, ExpectationValuesResult or ErrorResult. result.counts,
.values, .probabilities and .shots read the first entry, which is the whole answer
for a single-circuit submission.
A Session is a correlation scope and a budget envelope (ADR-0049 D4) — not a hardware reservation. It holds no backend and buys no queue priority; it groups a run's jobs for reporting and bounds what the run may spend.
jobs.result is valid once a Job is COMPLETED; asking earlier raises
InvalidRequestError.
Every failure is a QubitraError: AuthenticationError, NotFoundError,
InvalidRequestError, InsufficientCreditsError, or ProviderError. Each carries
the platform's RFC 9457 Problem Details body (ADR-0008) on .detail and its HTTP
status on .status_code.
Models are frozen pydantic models; the package ships py.typed, so a caller's type
checker sees the whole surface.
Layout
src/qubitra/— the public facade:client.py,models.py,errors.py,credentials.py.src/qubitra/_providers/— the adapter seam (ADR-0041 D2).base.pyis the protocol the facade depends on;qubitra.pyimplements it over/v1. A second platform slots in here without touching the facade.tests/— facade behaviour over a fake adapter, plus contract tests driving the adapter's real request path against an httpxMockTransport.
The SDK is synchronous (ADR-0041 D7); client objects own their transport, so an async twin is additive.
Tasks
mise exec -- uv run pytest pkg/niobium -q # tests
mise exec -- mypy pkg/niobium # types
mise exec -- ruff check pkg/niobium # lint
Release files for qubitra-sdk 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qubitra_sdk-0.3.0.tar.gz | 59.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qubitra_sdk-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 105.6 kB
Release files / qubitra_sdk-0.3.0.tar.gz
| Download URL | qubitra_sdk-0.3.0.tar.gz |
|---|---|
| Size | 59.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
910619f217284a18c22f6f9d40957d6206909ad964b87e6eb5661c770f9105e8
|
|
BLAKE2b-256 checksum How to use checksums |
c4300a4cc9c23b3040f568769bf8bf76d37f6b22793e7133b4103bf7845722b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / qubitra_sdk-0.3.0-py3-none-any.whl
| Download URL | qubitra_sdk-0.3.0-py3-none-any.whl |
|---|---|
| Size | 46.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
097bfa74895d877be951108f6ed2acee1b5a27a186ff456af0a7c7654b408658
|
|
BLAKE2b-256 checksum How to use checksums |
4e1ca17143207c7d7d2fc67f0a5eb061ca25b5b49737c6a51bc0be3b12aeef4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|