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.

License

Apache-2.0 (see LICENSE). The license covers this client library; the Pauli service and the "Pauli" marks are not licensed by it.

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.1.tar.gz (76.5 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.1-py3-none-any.whl (67.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pauli_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 76.5 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.1.tar.gz
Algorithm Hash digest
SHA256 b2ae1ef89805cee491c43ccbca5f35db87fb3a36d326f944dccb077a9de70349
MD5 111b8dbe14b6b0a86f3d9df1c120ca38
BLAKE2b-256 614bb3990018767ce1eb44ac104f69ad6a7e4388a8247e7403144a9c0c90af00

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pauli_sdk-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 67.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 02120ccd0242d34e63e9985f341227f44246fb3ba2c6b303789ef248b855aa10
MD5 984e17090df80423e3d3f3f00a72ba61
BLAKE2b-256 5e4ff5959dc8801e82665b6b9dae2fd54879c3f9d23ace8626efa8be169c2f21

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