Skip to main content

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.py is the protocol the facade depends on; qubitra.py implements 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 httpx MockTransport.

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)

Source distribution for qubitra-sdk 0.3.0
File Size Uploaded
qubitra_sdk-0.3.0.tar.gz 59.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qubitra-sdk 0.3.0
File Interpreter ABI Platform
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}

Release history Release notifications | RSS feed

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

This release

0.3.0 This release

2 release files

0.1.0

2 release files

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