Metadata-Version: 2.5
Name: qubitra-sdk
Version: 0.3.1
Summary: The Qubitra Python SDK: submit quantum circuits to backends on the Qubitra platform and read normalized results.
Project-URL: Homepage, https://github.com/Qubitra/q-platform
Project-URL: Repository, https://github.com/Qubitra/q-platform
Project-URL: Issues, https://github.com/Qubitra/q-platform/issues
Project-URL: Changelog, https://github.com/Qubitra/q-platform/blob/main/pkg/niobium/CHANGELOG.md
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: qpu,quantum,quantum-computing,qubitra,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.28
Requires-Dist: pydantic>=2.5
Provides-Extra: cirq
Requires-Dist: cirq-core>=1.6; extra == 'cirq'
Provides-Extra: pennylane
Requires-Dist: pennylane>=0.43; extra == 'pennylane'
Provides-Extra: qiskit
Requires-Dist: qiskit>=2.1; extra == 'qiskit'
Description-Content-Type: text/markdown

# Qubitra Python SDK

The Python client for the Qubitra platform. Submit quantum circuits to a backend,
wait for them to finish, and read normalized results.

Full documentation, including a quickstart and the API reference, is at
[q-plat-dev.cloud.qubitra.io/docs](https://q-plat-dev.cloud.qubitra.io/docs/).

## Install

```bash
pip install qubitra-sdk
```

The distribution is `qubitra-sdk` and the import is `qubitra`. Python 3.11 or newer
is required. Optional extras integrate with quantum frameworks: `qubitra-sdk[qiskit]`,
`qubitra-sdk[cirq]`, `qubitra-sdk[pennylane]`.

## Quickstart

Create an API key in the Qubitra console and set it as `QUBITRA_API_KEY`, then:

```python
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}
```

Note that `include "stdgates.inc";` is required in OpenQASM 3 programs: the language
defines no gates of its own, so `h` and `cx` are undefined without it.

## Configuration

| Variable | Default | Meaning |
| --- | --- | --- |
| `QUBITRA_API_KEY` | — | API key (`qpk_…`), required. Identifies your organization. |
| `QUBITRA_API_URL` | `https://api.qubitra.io` | The Qubitra deployment to reach. |

Both can also be passed as constructor arguments — `QubitraClient(api_key=…, api_url=…)` —
which take precedence over the environment.

## API surface

| Call | What it does |
| --- | --- |
| `client.backends.list()` / `.get(id)` | List the backends available to you, or read one by id. |
| `client.jobs.submit(...)` | Submit one circuit as a job; 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)` | Group a run of jobs and bound its budget. |
| `client.marketplace.offerings()` | Browse the marketplace catalogue. |

A job carries an ordered list of **PUBs** (Primitive Unit Blocs). A `Pub` is a circuit
plus optional `observables`, `parameter_values` rows, and a `shots` count. `JobResult.pubs`
is index-aligned with the submission; each entry is a `CountsResult`,
`ProbabilitiesResult`, `ExpectationValuesResult`, or `ErrorResult`. For a single-circuit
submission, the convenience properties `result.counts`, `.values`, `.probabilities`, and
`.shots` read the first entry.

A **Session** groups a run of jobs under one id and bounds what the run may spend via
`max_credits` and `max_seconds`. It does not reserve hardware or affect queue priority.

`jobs.result` is available once a job is `COMPLETED`; calling it earlier raises
`InvalidRequestError`.

## Errors

Every failure the SDK raises is a `QubitraError`. The subclasses are
`AuthenticationError`, `NotFoundError`, `InvalidRequestError`,
`InsufficientCreditsError`, and `ProviderError`. Each carries the platform's error body
on `.detail` and the HTTP status on `.status_code`.

## Typing

All models are frozen pydantic models, and the package ships `py.typed`, so the full
surface is visible to type checkers.
