Metadata-Version: 2.3
Name: xq-cloud
Version: 0.10.0
Summary: Add your description here
Author: Pit Hüne
Author-email: Pit Hüne <pit@xeedq.com>
Requires-Dist: fastapi[standard]>=0.116.1
Requires-Dist: numpy>=1.26.4
Requires-Dist: qiskit>=2.1.2
Requires-Dist: qiskit-aer>=0.17.1
Requires-Dist: sqlmodel>=0.0.25
Requires-Dist: requests>=2.31.0
Requires-Dist: scipy>=1.10.0
Requires-Dist: xq-pulse
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# XQ Cloud

`xq-cloud` is a Python client for submitting quantum computing jobs to XQ Cloud
and retrieving their results. It integrates with Qiskit and supports pulse
programs on compatible backends.

## Installation

Requires Python 3.10 or later.

```bash
pip install xq-cloud
```

## Connect and choose a backend

You need XQ Cloud access credentials and permission to use a backend. Set the
environment variables `XQ_CLOUD_CLIENT_ID` and `XQ_CLOUD_CLIENT_SECRET` to the
Client ID and Client Secret provided with your account, then connect:

```python
import os

from xq_cloud import XQCloudProvider

provider = XQCloudProvider(
    cloudflare_client_id=os.environ["XQ_CLOUD_CLIENT_ID"],
    cloudflare_client_secret=os.environ["XQ_CLOUD_CLIENT_SECRET"],
)

for backend in provider.backends():
    print(backend.name)
```

## Submit a job and get results

Replace `YOUR_BACKEND_NAME` with a name returned above. This example prepares a
single-qubit circuit, compiles it for the selected backend, and submits it for
population readout. Readout is handled by the backend; omit measurement
instructions from the circuit.

```python
from qiskit import QuantumCircuit

from xq_cloud.transpiler import transpile

backend = provider.backends(name="YOUR_BACKEND_NAME")[0]

circuit = QuantumCircuit(1)
circuit.h(0)
compiled_circuit = transpile(circuit, target=backend.target)

job = backend.run(
    compiled_circuit,
    shots=1000,
    name="first-experiment",
    metadata={"description": "Single-qubit superposition"},
)
job.submit()
print("Job ID:", job.job_id())  # Save this ID to retrieve results later.

result = job.result(timeout_seconds=300)
print(result.results[0].data.expectation_values)
```

`backend.run(...)` prepares the job; `job.submit()` sends it to the queue.
`job.result(...)` waits for completion and returns a Qiskit `Result`.
The optional `name` and JSON-object `metadata` are stored with the job. Names
can be reused; every submission receives its own unique job ID.

## Retrieve results later

After connecting again, use a saved job ID to wait for its result payload:

```python
job_id = "YOUR_SAVED_JOB_ID"
results = provider.client.wait_for_result(job_id, timeout_seconds=300)
print(results)
```

To check once without waiting, use `provider.client.get_result(job_id)` and
inspect its `status`, `result`, and `error` fields. A waiting timeout raises
`TimeoutError` and leaves the job running or queued; you can request its results
again later. API errors and failed jobs raise `XQCloudApiError` when waiting.

You can also find your jobs by name:

```python
for saved_job in provider.client.get_jobs(name="first-experiment"):
    print(saved_job.job_id, saved_job.status, saved_job.metadata)
```

Name matching is exact. Add `backend=...` or `status=...` to narrow the list.
