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.
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.
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
shellpip 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 · Pythonfrom 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().
Pythonjob = 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.
Pythonfrom 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/.
shellqly 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.
Pythonfor 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.
Pythonjob = 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:
Pythonfrom 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
Ready to run something? Create a key, then submit your first circuit from the shell in under a minute.