Skip to content

API reference

QubitraClient

Client for the Qubitra quantum platform.

The API key resolves from api_key, then QUBITRA_API_KEY; the platform it reaches from api_url, then QUBITRA_API_URL, then the hosted deployment. A custom adapter substitutes the whole transport layer.

QubitraClient(*, api_key: str | None = None, api_url: str | None = None, adapter: ProviderAdapter | None = None) -> None

The client is a context manager: with QubitraClient() as client: closes the connection pool on exit, and close() does the same by hand.

client.close() -> None

Release the underlying HTTP connection pool.

client.backends

The catalogue of execution targets available to the caller's organization.

client.backends.list() -> list[Backend]
client.backends.get(backend_id: str) -> Backend

client.jobs

Jobs: submission, status, results and cancellation.

A job carries an ordered list of PUBs, and its result comes back index-aligned with them. submit is the one-circuit form and builds a job of a single PUB; run takes the list.

client.jobs.submit(*, backend_id: str, circuit: str, circuit_format: CircuitFormat = CircuitFormat.OPENQASM_3, shots: int = 1024, name: str | None = None, observables: Sequence[Observable] | None = None, parameter_values: Sequence[Sequence[float]] | None = None, session_id: str | None = None) -> Job

Submit one circuit — the common case, as a job of a single PUB.

Everything a PUB can carry is available here for one circuit: pass observables for an expectation value instead of counts, and parameter_values to sweep the circuit's input declarations. For several circuits in one job, use run.

session_id puts the job inside a Session (client.sessions), which groups a run of jobs and bounds the run's budget.

client.jobs.run(*, backend_id: str, pubs: Sequence[Pub], shots: int | None = None, name: str | None = None, session_id: str | None = None) -> Job

Submit an ordered list of PUBs as one job.

JobResult.pubs comes back index-aligned with this list: entry *i* belongs to pubs[i] regardless of what happened to the others, including a PUB that failed on its own.

shots is the job's default; a PUB carrying its own overrides it. Not every backend accepts more than one PUB; one that does not rejects the whole submission at submit.

client.jobs.list() -> list[Job]

The caller's organization's jobs, newest first.

client.jobs.get(job_id: str) -> Job
client.jobs.result(job_id: str) -> JobResult
client.jobs.cancel(job_id: str) -> None
client.jobs.wait(job_id: str, *, timeout: float = 300.0, poll_interval: float = 5.0) -> Job

Poll until the job reaches a terminal status; raises on timeout.

client.sessions

Sessions: group a run of jobs and bound what the run may spend.

Jobs submitted with a session's id are reported as one run, and the session's max_credits and max_seconds bound what the whole run may spend — the useful bound for a variational loop, where a per-job limit says little about the total.

A Qubitra session is not a hardware reservation: it does not reserve a backend, grant queue priority, or make any scheduling promise. Sessions are free to open and free to leave open.

client.sessions.create(*, name: str | None = None, max_credits: float | None = None, max_seconds: int | None = None) -> Session

Open a session. Pass its id as session_id when submitting jobs.

max_credits and max_seconds are the run's budget, enforced across every job in it; omitting both opens a session that correlates without bounding. A job that would take the run past either bound is rejected at submit.

client.sessions.list() -> list[Session]

The caller's organization's sessions, newest first.

client.sessions.get(session_id: str) -> Session

One session, including what it has spent so far against its budget.

client.sessions.close(session_id: str) -> Session

Close a session and return its final state.

Closing stops further jobs joining the session, which makes the run's totals final.

client.marketplace

client.marketplace.offerings() -> list[Offering]

Models

Every model is frozen, so an instance is a snapshot rather than a handle — re-read the platform to see a change. Unset optional fields are None: the SDK reports what the platform sent and invents nothing.

ApiKeyCredentials

FieldTypeDefault
tokenstrrequired

Backend

An execution target: a simulator, a QPU, or a vendor service.

A Backend is identified by a Qubitra-owned slug, and the model describes capability — what a caller needs to choose one. There is no vendor, hardware owner, or access-tier field; the hardware behind a Backend can change without caller code changing.

basis_gates, operations, connectivity and calibration are absent until known: they are populated from what a backend publishes, so a backend whose metadata has not yet been populated carries None. None means *not reported*, never *not supported* — treat these fields as background information rather than as a guarantee, and do not gate a submission on one.

FieldTypeDefault
idstrrequired
namestr | NoneNone
typeBackendType | NoneNone
technologystr | NoneNone
qubit_countint | NoneNone
queue_sizeint | NoneNone
availablebool | NoneNone
shots_minint | NoneNone
shots_maxint | NoneNone
supported_formatstuple[CircuitFormat, ...]()
basis_gatestuple[str, ...] | NoneNone
operationstuple[str, ...] | NoneNone
connectivitytuple[tuple[int, int], ...] | NoneNone
calibrationdict[str, Any] | NoneNone

CountsResult

Measured bitstring counts — what a sampler PUB returns.

FieldTypeDefault
typeLiteral[<COUNTS: 'counts'>]ResultType.COUNTS
countsdict[str, int]{}
shotsint | NoneNone

ErrorResult

One PUB failed while others may have succeeded.

Results are index-aligned with submission, so a failed PUB occupies its own slot rather than collapsing the whole job's result.

FieldTypeDefault
typeLiteral[<ERROR: 'error'>]ResultType.ERROR
detailstr''

ExpectationValuesResult

Expectation values — what an estimator PUB returns.

values is index-aligned with the PUB's observables, or with its parameter rows when the PUB is a sweep of one observable. stds carries the standard error of each value where the backend reports one; an exact simulator samples nothing, so it may report none.

FieldTypeDefault
typeLiteral[<EXPECTATION_VALUES: 'expectation_values'>]ResultType.EXPECTATION_VALUES
valuestuple[float, ...]()
stdstuple[float, ...] | NoneNone
shotsint | NoneNone

Job

One asynchronous execution of an ordered list of PUBs on a Backend.

FieldTypeDefault
idstrrequired
backend_idstr | NoneNone
statusJobStatusJobStatus.UNKNOWN
shotsint | NoneNone
namestr | NoneNone
session_idstr | NoneNone
created_atstr | NoneNone
ended_atstr | NoneNone
errorstr | NoneNone

JobResult

The normalized result of a completed Job: one entry per submitted PUB.

pubs is index-aligned with the job's PUB list, so pubs[0] belongs to the first PUB whatever the others did. The convenience properties read the first entry, which is the whole answer for a single-circuit submission.

FieldTypeDefault
pubstuple[Annotated[CountsResult | ProbabilitiesResult | ExpectationValuesResult | ErrorResult, FieldInfo(annotation=NoneType, required=True, discriminator='type')], ...]()
JobResult.first: PubResult | None

The first PUB's result, or None for a job that produced none.

JobResult.kind: str

The first PUB's result type, as a string; "unknown" when there is none.

JobResult.counts: dict[str, int] | None

The first PUB's counts, or None when it did not return counts.

JobResult.probabilities: dict[str, float] | None

The first PUB's probabilities, or None when it did not return them.

JobResult.values: tuple[float, ...] | None

The first PUB's expectation values, or None when it returned none.

JobResult.shots: int | None

The shot count the first PUB ran at, where the backend reported one.

Observable

A weighted sum of Pauli strings, whose expectation value an estimator PUB returns.

num_qubits is the width the observable is written against — the circuit's width, not the number of qubits the terms happen to name.

The Hamiltonian 1.5·Z₀Z₁ − 0.5·X₀ on two qubits::

Observable( num_qubits=2, terms=( PauliTerm(pauli="ZZ", qubits=(0, 1), coefficient=1.5), PauliTerm(pauli="X", qubits=(0,), coefficient=-0.5), ), )

FieldTypeDefault
num_qubitsintrequired
termstuple[PauliTerm, ...]()

Offering

Anything published to the marketplace.

FieldTypeDefault
idstrrequired
namestr | NoneNone
summarystr | NoneNone
typeOfferingTypeOfferingType.APPLICATION
provider_namestr | NoneNone

PauliTerm

One weighted Pauli string of an Observable.

pauli is a string of I/X/Y/Z, one character per entry in qubits: PauliTerm(pauli="ZZ", qubits=(0, 1)) measures Z on qubit 0 and Z on qubit 1. The representation is sparse, so a two-qubit term on a 26-qubit circuit names two qubits rather than padding to the width.

FieldTypeDefault
paulistrrequired
qubitstuple[int, ...]required
coefficientfloat1.0

ProbabilitiesResult

A quasi-distribution over bitstrings, for a backend that reports one.

FieldTypeDefault
typeLiteral[<PROBABILITIES: 'probabilities'>]ResultType.PROBABILITIES
probabilitiesdict[str, float]{}
shotsint | NoneNone

Pub

A Primitive Unit Bloc: one circuit and everything needed to run it.

A job carries an ordered list of PUBs, and a PUB's contents determine what kind of result it returns:

- circuit alone — **sampler**: measured counts. - circuit + observables — **estimator**: an expectation value per observable, and no measurement instructions in the circuit. - either, plus parameter_values — a **sweep**: the circuit is run once per row.

parameter_values is a list of rows, each row one value per input declaration in the circuit, in declaration order. Parameter binding is expressed in the circuit itself: an OpenQASM 3 input float[64] theta; declares the value a row supplies. A published cap bounds rows per PUB and is enforced at submit.

shots overrides the job's shot count for this PUB alone; None takes the job's.

FieldTypeDefault
circuitstrrequired
formatCircuitFormatCircuitFormat.OPENQASM_3
observablestuple[Observable, ...]()
parameter_valuestuple[tuple[float, ...], ...]()
shotsint | NoneNone

Session

A run of Jobs, grouped under one id and bounded by a budget.

Jobs submitted with this session's id are reported as one run, and max_credits and max_seconds bound what the whole run may spend, enforced across it.

A Qubitra session is not a hardware reservation: it does not reserve a backend, grant queue priority, or make any scheduling promise. This differs from sessions on some other platforms, such as Qiskit Runtime.

credits_used and elapsed_seconds are what the platform has counted against the bounds so far.

FieldTypeDefault
idstrrequired
namestr | NoneNone
statusSessionStatusSessionStatus.UNKNOWN
max_creditsfloat | NoneNone
max_secondsint | NoneNone
credits_usedfloat | NoneNone
elapsed_secondsint | NoneNone
created_atstr | NoneNone
ended_atstr | NoneNone

Enumerations

All four are string enums, so a member compares equal to its wire value and prints as itself. A value this SDK version does not know is not fatal: an unrecognised status reads as JobStatus.UNKNOWN and an unrecognised circuit format is dropped from a backend's supported_formats.

BackendType

  • QPU
  • SIMULATOR
  • ANNEALER

CircuitFormat

Circuit interchange formats a job may be submitted in.

The first four are text programs. IONQ_CIRCUIT is a JSON circuit document — a gateset, a qubit count and a list of gates — so a circuit in that format is JSON text rather than program source. It is still passed as a string.

A backend reports what it accepts as Backend.supported_formats; a backend that reports none places no constraint of its own.

OPENQASM_3 is accepted as static circuits with parameters, not as the whole language: for/while loops, def subroutines, classical int declarations and mid-circuit branching are rejected. The circuit-formats documentation page describes the boundary in full.

  • OPENQASM_2
  • OPENQASM_3
  • QIR
  • QPY
  • IONQ_CIRCUIT

JobStatus

  • UNKNOWN
  • PENDING
  • RUNNING
  • CANCELLING
  • COMPLETED
  • FAILED
  • CANCELLED
  • ABORTED
JobStatus.is_terminal: bool

OfferingType

  • APPLICATION
  • TOOL_LIBRARY
  • BACKEND
  • INFRASTRUCTURE
  • EXPERTISE

ResultType

What a per-PUB result carries. The discriminator of the PubResult union.

  • COUNTScounts
  • PROBABILITIESprobabilities
  • EXPECTATION_VALUESexpectation_values
  • ERRORerror

SessionStatus

  • UNKNOWN
  • OPEN
  • CLOSED
  • EXPIRED

Errors

Every failure the SDK raises is a QubitraError, so oneexcept QubitraError is a complete catch. What a caller does about each is on the error handling page.

  • QubitraError

    Base class for all errors raised by the Qubitra SDK.

    Attributesmessage: str, status_code: int | None, detail: Any

  • AuthenticationErrorextends QubitraError

    Missing or rejected credentials.

  • InsufficientCreditsErrorextends QubitraError

    The organization cannot pay for the operation. The request was well-formed; the same call succeeds once the balance covers it.

  • InvalidRequestErrorextends QubitraError

    The platform rejected the request as malformed or unprocessable.

  • NotFoundErrorextends QubitraError

    The requested resource does not exist.

  • ProviderErrorextends QubitraError

    An upstream platform failure that maps to no more specific error.

Configuration

Constructor arguments take precedence over the environment. These values are read from the package's own constants.

ConstantKindValue
ENV_API_KEYenvironment variableQUBITRA_API_KEY
ENV_API_URLenvironment variableQUBITRA_API_URL
DEFAULT_API_URLdefaulthttps://api.qubitra.io
DEFAULT_TIMEOUT_Sdefault30.0
DEFAULT_POLL_INTERVAL_Sdefault5.0
DEFAULT_WAIT_TIMEOUT_Sdefault300.0