Skip to main content

Official Python client for the Pauli quantum compute gateway: OpenQASM 3 in, canonical counts out

Project description

pauli-sdk

Official Python client for Pauli, the API gateway for quantum compute: OpenQASM 3 in, canonical counts out, priced on every eligible device before anything runs.

pip install pauli-sdk
from pauli_sdk import Pauli

client = Pauli()  # reads PAULI_API_KEY
job = client.jobs.run(GHZ_QASM3, shots=1000, policy="cheapest", max_spend_usd="1.50")
res = job.results()
print(res.counts)             # {'000': 489, '111': 511} — cbit0_left on every backend
print(res.billing.price_usd)  # Decimal('0.685750'): the exact wallet debit

Pauli and AsyncPauli expose the same surface (the sync client is generated from the async source). Get a key at pauli.xyz; docs live at pauli.xyz/docs, the full endpoint reference at pauli.xyz/reference.

Why this API is different, in SDK terms

  • Price before you run. client.jobs.estimate(qasm) prices the circuit on every eligible device (cheapest first, with reasoned exclusions); client.jobs.dry_run(qasm, ...) previews the exact submit — routing decision, exact wallet debit, admission check — for free. The 202 from submit() already carries the routing decision and cost estimate.

  • Money is exact. Every USD figure is a decimal.Decimal parsed from the API's decimal strings. Passing a float where money is expected raises: use "1.50" or Decimal("1.50").

  • One bit ordering. Every backend's counts normalize to cbit0_left (leftmost character = classical bit 0 of the first-declared register, registers in declaration order). res.counts is a Counts with probabilities(), marginal("c"), top(n), and to_qiskit() — the one framework whose convention reverses ours.

  • Safe retries. submit() auto-generates an Idempotency-Key and reuses it across network retries, so a retried submit converges on one job; job.replayed tells you when the server answered from an earlier identical submit. Transient failures retry with jittered backoff, honoring Retry-After.

  • Typed failure modes. Errors are keyed on the API's stable machine codes (GET /public/errors is the registry; exc.code is always set). The fundable 402 is first-class:

    import pauli_sdk
    
    try:
        job = client.jobs.submit(qasm, shots=100_000)
    except pauli_sdk.InsufficientCreditsError as e:
        print(e.shortfall_usd)       # Decimal
        print(e.challenge.checkout)  # fund it, then resubmit with the same idempotency key
    
  • Webhooks verified in one call. pauli_sdk.webhooks.unwrap(body, headers, secret=...) implements the documented X-Pauli-Signature recipe (HMAC-SHA256, 5-minute replay tolerance, rotation overlap) and hands back the parsed event; dedupe on event.event_id.

  • BYOK. Register your own provider credentials (client.credentials.put("ionq", api_key=..., accept_provider_terms=True)) and hardware runs under them automatically — the provider bills you directly and the wallet pays only the platform fee. Secrets are write-only; Braket uses client.credentials.braket_external_id() first.

  • Keyless public surface. Pauli() with no key still serves client.public.*: the live device registry, anonymous fleet estimates, the error registry, published benchmarks.

Waiting on jobs

job.wait() polls with jittered exponential backoff (0.5 s → 15 s); client.jobs.run(...) is submit + wait, raising JobFailedError / JobCancelledError on the other terminal states. For long queues prefer webhooks (webhook_url= per job, or workspace endpoints via client.webhooks.create_endpoint(...)).

job = client.jobs.submit(qasm, policy="highest_fidelity")
print(job.routing_decision.selected_device, job.cost_estimate.amount)
status = job.wait(timeout=3600)

Agents: Pauli also serves a remote MCP endpoint at https://pauli.xyz/mcp (same bearer key). This SDK and MCP are two veneers over the same REST API — same auth, limits, and billing rails.

Versioning

The SDK is semver, currently 0.x; the API is /v1 and additive. Response models tolerate unknown fields, so an older SDK keeps working against a newer server.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pauli_sdk-0.1.0.tar.gz (72.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pauli_sdk-0.1.0-py3-none-any.whl (62.8 kB view details)

Uploaded Python 3

File details

Details for the file pauli_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: pauli_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 72.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pauli_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 68ea9b47ab9d774c67d6916904d144ea007c2dc101bd039ab54ba849d7bc076d
MD5 ff0ff7b23a88a6affa789ed0ddc94e15
BLAKE2b-256 94e1e86595cbd0b286081d5110daec0e89cff4323bab0781245175bd2f0b1736

See more details on using hashes here.

File details

Details for the file pauli_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pauli_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 62.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pauli_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c2675da0a171f8fee5d9fea96392768f726a06cd2d322b1f7ae18e4347d8b21
MD5 b986842b6573e77d96f4aa652b410793
BLAKE2b-256 0f81cd69d74e62a19f5d0fe7fae705314f8cb669375ce8297238b54d4afb3b8a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page