Python SDKqly-sdk 0.2MIT

Qly from your terminal

qly-sdk is the Python client for Qly. Write a circuit in OpenQASM or Qiskit, submit it to real quantum hardware or a simulator, and pull the results back as Python objects. Everything the Compute page does, scriptable.

Get an API key →qly-sdk on PyPI

Overview

The package name on PyPI is qly-sdk; everything else is just qly. You import qly in Python, and the install also puts a qly command on your PATH for shell workflows and CI.

Submit
OpenQASM strings or Qiskit circuits, to QPUs and simulators across providers.
Poll
Blocking run(), or submit() and check status yourself. Counts come back as dicts.
Operate
List devices, check balance, script the whole loop from a shell or notebook.

Jobs submitted through the SDK land on the same pipeline as the Compute page: they show up on your Jobs page with full histograms, and they bill against the same prepaid balance.

Install & authenticate

shell
pip install qly-sdk

Sign in and create a key on the API Keys page. The secret is shown once and looks like qly_live_…. Pass it as Qly(api_key=…), or set QLY_API_KEY in your environment and construct the client with no arguments.

Quickstart

A Bell pair on real IBM hardware in a dozen lines. run() submits and blocks until the job finishes, then hands you the counts.

bell.py · Python
from qly import Qly client = Qly(api_key="qly_live_...") # or set QLY_API_KEY bell = """ OPENQASM 2.0; include "qelib1.inc"; qreg q[2]; creg c[2]; h q[0]; cx q[0], q[1]; measure q -> c; """ job = client.run(bell, provider="ibm", device="ibm_kingston", shots=1024) print(job.counts) # {'00': 503, '11': 521}

Swap device for a simulator while you iterate; simulators are free and the code path is identical.

Submit & poll separately

Real QPUs queue, so blocking is not always what you want. submit() returns immediately with a job handle; wait() blocks until it reaches a terminal state, or poll by hand with get_job().

Python
job = client.submit(bell, provider="ibm", device="ibm_kingston", shots=1024) print(job.id, job.status) # 'd4a…', 'PENDING' job = client.wait(job) # blocks until terminal, raises on failure print(job.counts) # or poll by hand: job = client.get_job(job.id) if job.done: print(job.results)

From a Qiskit circuit

Install the extra with pip install "qly-sdk[qiskit]" and pass a QuantumCircuit directly; no manual QASM export needed.

Python
from qiskit import QuantumCircuit from qly import Qly qc = QuantumCircuit(2, 2) qc.h(0) qc.cx(0, 1) qc.measure([0, 1], [0, 1]) client = Qly() job = client.run(circuit=qc, provider="ionq", device="simulator", shots=512) print(job.counts)

Command line

The install ships a qly command, so you can run circuits without writing any Python. qly configure stores your key once in ~/.config/qly/.

shell
qly configure # paste your key once qly devices # what can I run on? qly balance qly submit bell.qasm --provider ionq --device simulator --shots 1024 --wait qly jobs --limit 10 # recent jobs qly job <job-id> # status + measurement histogram

submit --wait polls until the job finishes and prints the counts. Every command takes --json for machine-readable output, and --api-key / QLY_API_KEY override the stored key, which is what you want in CI.

Devices & balance

Enumerate every device your account can target, with qubit counts and simulator flags, and check your balance before a big batch.

Python
for d in client.devices(): print(d.provider, d.id, d.qubits, "sim" if d.is_simulator else "qpu") print(client.balance().formatted) # '$12.40'

Estimator: expectation values

On IBM devices you can request Pauli expectation values instead of raw shot counts, which is the primitive variational algorithms like VQE consume.

Python
job = client.run( ansatz_qasm, provider="ibm", device="ibm_kingston", primitive="estimator", observables=["ZZ", "IZ", "ZI"], shots=4096, ) print(job.results) # {'evs': [...], 'stds': [...]}

Error handling

Failures raise typed exceptions with the fields you need to react programmatically:

AuthenticationErrormissing, invalid, or revoked key
InsufficientBalanceErrornot enough credit; carries .estimated_cents and .balance_cents
RateLimitErrortoo many submissions; carries .retry_after
JobFailedErrorjob ended FAILED / ERROR / CANCELLED; .job has the detail
JobTimeoutErrorrun() or wait() timed out
APIErroranything else; carries .status_code and .payload
Python
from qly import InsufficientBalanceError try: client.run(circuit, provider="ibm", device="ibm_kingston") except InsufficientBalanceError as e: print(f"Need ~{e.estimated_cents}¢, have {e.balance_cents}¢")

Configuration

ArgumentEnv varDefault
api_keyQLY_API_KEYrequired
base_urlQLY_BASE_URLhttps://qly.app

Ready to run something? Create a key, then submit your first circuit from the shell in under a minute.

Get an API key →Prefer the IDE? Tutorials →