Skip to main content

Open Quantum Python SDK

A lightweight, modern Python SDK for the Open Quantum Platform.

Features:

  • Management API — list organizations, backend classes, and providers
  • Scheduler API — job categories, upload, prepare, submit, poll, and one-call submit_job()
  • Input formats — OpenQASM (qasm) by default; other formats via input_format when the backend supports them
  • Smart defaults — auto-select execution plan & queue priority from quote
  • Thread-safe auth — Keycloak client-credentials with auto-refresh
  • Automatic output download — download_job_output() returns parsed JSON
  • Calibration download — download_job_calibration() when the job has calibration_data_url

Installation

pip install -U openquantum-sdk
# or local dev:
pip install -e .

Python 3.8+ required.

Authentication

Download from Open Quantum SDK Keys:

{
  "client_id": "s_abc123...",
  "client_secret": "e460c8..."
}
export OPENQUANTUM_SDK_KEY=/path/to/sdk-key.json

Option 2: Direct in Code

from openquantum_sdk.auth import ClientCredentials, ClientCredentialsAuth

auth = ClientCredentialsAuth(
    creds=ClientCredentials(client_id="s_...", client_secret="e460c8...")
)

Option 3: Environment Variables

export OPENQUANTUM_CLIENT_ID=s_...
export OPENQUANTUM_CLIENT_SECRET=e460c8...
from openquantum_sdk.clients import SchedulerClient, ManagementClient, JobSubmissionConfig
from openquantum_sdk.enums import ExecutionPlanType, QueuePriorityType
import json

# 1. Instantiate clients (auto-loads auth from env)
scheduler = SchedulerClient()
management = ManagementClient()

try:
    # 2. Discover your Organization ID
    print("Discovering organization...")
    orgs = management.list_user_organizations()
    org_id = orgs.organizations[0].id
    print(f" > Using Org: {orgs.organizations[0].name}")

    # 2.5 Discover available backend providers
    print("\nAvailable providers:")
    providers = management.list_providers()
    for p in providers.providers:
        print(f" > {p.name} ({p.short_code or 'no short code'}) — {p.description}")

    # 2.6 Discover backend classes
    print("\nAvailable backend classes:")
    classes = management.list_backend_classes()
    for bc in classes.backend_classes:
        print(f" > {bc.name} ({bc.short_code or 'no short code'}) — {bc.type}")
        print(f"   ├ Status: {bc.status or 'Unknown'} | Queue depth: {bc.queue_depth or 'N/A'}")
        print(f"   └ Use: '{bc.short_code or bc.id}' in backend_class_id")

    # 3. Define config
    config = JobSubmissionConfig(
        organization_id=org_id,
        backend_class_id="iqm:emerald",
        name="Bell State SDK Quickstart",
        job_subcategory_id="fin:port", # Finance Portfolio Optimization
        shots=100,
        execution_plan="auto",
        queue_priority="auto",
        auto_approve_quote=True,
        verbose=True
    )

    # 4. Submit + wait + get result
    dummy_qasm = b"OPENQASM 2.0; include 'qelib1.inc'; qreg q[2]; creg c[2]; h q[0]; cx q[0],q[1]; measure q -> c;"
    job = scheduler.submit_job(config, file_content=dummy_qasm)

    # 5. Download and print parsed JSON output
    print("\n--- JOB SUCCEEDED ---")
    print(f"Job ID: {job.id}")
    print(f"Status: {job.status}")

    if job.output_data_url:
        output_json = scheduler.download_job_output(job)
        print("\n--- JOB OUTPUT (JSON) ---")
        print(json.dumps(output_json, indent=2))
    else:
        print("No output available.")

    if job.calibration_data_url:
        cal_json = scheduler.download_job_calibration(job)
        print("\n--- CALIBRATION (JSON) ---")
        print(json.dumps(cal_json, indent=2))

except Exception as e:
    print(f"\n--- JOB FAILED ---")
    print(f"Error: {e}")

finally:
    scheduler.close()
    management.close()

Handles everything in one call — including automatic JSON download.

Quickstart: Low-Level (Advanced)

from openquantum_sdk.clients import SchedulerClient, ManagementClient
from openquantum_sdk.models import JobPreparationCreate, JobCreate
from openquantum_sdk.utils import poll_for_status
import json

scheduler = SchedulerClient()
management = ManagementClient()

try:
    # 1. Get org
    org = management.list_user_organizations().organizations[0]

    # 1.5 List providers & backend classes
    print("Providers:")
    for p in management.list_providers().providers:
        print(f" - {p.name} ({p.short_code})")

    print("\nBackend classes:")
    for bc in management.list_backend_classes().backend_classes:
        print(f" - {bc.name} [{bc.type}] — {bc.short_code or bc.id}")

    # 2. Choose IDs
    MY_BACKEND = "iqm:emerald"
    MY_SUBCATEGORY = "fin:port"

    # 3. Upload
    upload_id = scheduler.upload_job_input(file_path="circuit.qasm")

    # 4. Prepare
    prep = JobPreparationCreate(
        organization_id=org.id,
        backend_class_id=MY_BACKEND,
        name="Low-Level Test",
        upload_endpoint_id=upload_id,
        job_subcategory_id=MY_SUBCATEGORY,
        shots=100,
        configuration_data={}
    )
    prep_resp = scheduler.prepare_job(prep)

    # 5. Poll preparation
    def get_prep_status(prep_id: str):
        result = scheduler.get_preparation_result(prep_id)
        done = result.status in ("Completed", "Failed")
        return done, result

    result = poll_for_status(
        get_status_fn=get_prep_status,
        resource_id=prep_resp.id,
        interval=2.0,
        timeout=300
    )

    if result.status == "Failed":
        raise RuntimeError(f"Preparation failed: {result.message or 'Unknown error'}")

    # Quote inspection
    print("\nQuote received:")
    for plan in result.quote:
        print(f" • {plan.name} — Base: {plan.price} credit{'s' if plan.price != 1 else ''}")
        for qp in plan.queue_priorities:
            total = plan.price + qp.price_increase
            print(f"    ├ {qp.name}: +{qp.price_increase} → Total: {total}")
        print(f"    └ Plan ID: {plan.execution_plan_id}")

    # 6. Select cheapest
    cheapest_plan = min(result.quote, key=lambda p: p.price)
    cheapest_prio = min(cheapest_plan.queue_priorities, key=lambda q: q.price_increase)

    # 7. Create job (organization comes from the preparation)
    job = JobCreate(
        job_preparation_id=prep_resp.id,
        execution_plan_id=cheapest_plan.execution_plan_id,
        queue_priority_id=cheapest_prio.queue_priority_id,
    )

    job_resp = scheduler.create_job(job)

    # 8. Poll completion
    def get_job_status(job_id: str):
        job_obj = scheduler.get_job(job_id)
        done = job_obj.status in ("Completed", "Failed", "Canceled")
        return done, job_obj

    final_job = poll_for_status(
        get_status_fn=get_job_status,
        resource_id=job_resp.id,
        interval=5.0,
        timeout=86_400,
    )

    print(f"\nJob finished: {final_job.status}")

    # 9. Download and print JSON output
    if final_job.output_data_url:
        output_json = scheduler.download_job_output(final_job)
        print("\n--- JOB OUTPUT (JSON) ---")
        print(json.dumps(output_json, indent=2))
    else:
        print("No output available.")

finally:
    scheduler.close()
    management.close()

High-Level API: submit_job()

Parameter Type Default Description
config JobSubmissionConfig — All job metadata
file_path str — Input file
file_content bytes — Or pass bytes

JobSubmissionConfig

Field Type Default Notes
organization_id str — Required
backend_class_id str — Required (short code or UUID)
job_subcategory_id str — Required
name str — Required
shots int — Required
configuration_data Dict[str, Any] None
execution_plan ExecutionPlanType | "auto" "auto"
queue_priority QueuePriorityType | "auto" "auto"
auto_approve_quote bool True Set False in notebooks
job_timeout_seconds int 86400 1 day
input_format str "qasm" OpenQASM by default; other values only if listed in backend supported_formats
submitted_with str "sdk" Client surface for analytics

API Reference

SchedulerClient

Method Returns Description
__init__(auth[ClientCredentialsAuth])
get_job_categories(limit=20, cursor=...) PaginatedJobCategories List top-level categories
get_job_subcategories(category_id, limit=20, cursor=...) PaginatedJobCategories List subcategories
upload_job_input(file_path=... or file_content=...) str Returns upload ID
prepare_job(JobPreparationCreate) JobPreparationResponse Starts preparation
get_preparation_result(preparation_id) JobPreparationResultResponse Includes .quote
create_job(JobCreate) JobRead Submits job
get_job(job_id) JobRead Fetch job status
cancel_job(job_id) None Cancel running job
list_jobs(organization_id, limit=20, cursor=..., status=...) PaginatedJobs List your jobs
download_job_output(job) Any Downloads + parses JSON output
download_job_calibration(job) Any Downloads + parses calibration JSON (when tagged)
submit_job(config, file_path=... or file_content=...) JobRead One-call submission + polling

ManagementClient

Method Returns Description
__init__(auth[ClientCredentialsAuth])
list_user_organizations(limit=20, cursor=...) PaginatedOrganizations Your orgs
list_providers(limit=20, cursor=...) PaginatedProviders All backend providers
list_backend_classes(provider_id=None, limit=20, cursor=...) PaginatedBackendClasses Available backends
get_credit_balance(organization_id: str) CreditBalanceRead Get current credit balance

Data Models

Model Key Fields
BackendClassRead id, name, description, type, provider_id, short_code, queue_depth, accepting_jobs, status
ErrorResponse status_code, message: List[str], type, error_code (request id)
JobCategoryRead id, name, short_code
JobCreate job_preparation_id, execution_plan_id, queue_priority_id, optional organization_id
JobList id, backend_class_id, name, status, backend_name, output_data_url, calibration_data_url, credits_used, submitted_at
JobPreparationCreate organization_id, backend_class_id, name, upload_endpoint_id, job_subcategory_id, shots, configuration_data, input_format, submitted_with
JobPreparationResponse id
JobPreparationResultResponse organization_id, backend_class_id, status, name, input_data_url, job_category_id, job_subcategory_id, shots, quote: List[QuotePlan], message, configuration_data
JobPreparationUploadResponse id, url
JobRead id, status, input_data_url, job_preparation_id, execution_plan_id, queue_priority_id, message, output_data_url, calibration_data_url, transaction_id, submitted_at
OrganizationRead id, name
PaginatedBackendClasses backend_classes: List[BackendClassRead], pagination: PaginationInfo
PaginatedJobCategories categories: List[JobCategoryRead], pagination: PaginationInfo
PaginatedJobs jobs: List[JobList], pagination: PaginationInfo
PaginatedOrganizations organizations: List[OrganizationRead], pagination: PaginationInfo
PaginatedProviders providers: List[ProviderRead], pagination: PaginationInfo
PaginationInfo next_cursor
ProviderRead id, name, description, short_code
QueuePriority name, description, price_increase, queue_priority_id
QuotePlan name, price, description, execution_plan_id, queue_priorities: List[QueuePriority]

Utils: poll_for_status()

from openquantum_sdk.utils import poll_for_status
Parameter Type Default Description
get_status_fn Callable[[str], Tuple[bool, Any]] Function to be polled
resource_id str id to be passed to status function: get_status_fn(resource_id)
interval int 5 Number of seconds to wait before next call of status function
timeout int 300 Number of seconds before timeout

Enums

from openquantum_sdk.enums import ExecutionPlanType, QueuePriorityType
Enum Values
ExecutionPlanType PUBLIC, PRIVATE
QueuePriorityType STANDARD, PRIORITY, INSTANT

CLI (Experimental)

python -m openquantum_sdk --sdk-key ./key.json \
                          --input bell.qasm \
                          --backend "iqm:emerald" \
                          --name "CLI Circuit" \
                          --subcategory "mathematics:linear-systems" \
                          --shots 100 \
                          --auto-approve

Automatically downloads and pretty-prints JSON output.

Short Codes

Backends

Provider Backend Short Code
AQT Ibex-Q1 aqt:ibex-q1
IonQ Forte Enterprise ionq:forte-ent
IonQ Forte-1 ionq:forte-1
IQM Emerald iqm:emerald
IQM Garnet iqm:garnet
Rigetti Cepheus-1-108Q rigetti:cepheus-108q

Note: This list may be modified as backends are added or removed from the platform. For the most up-to-date list, run the following code:

backends = management.list_backend_classes().backend_classes

print('| Name | Short Code | Online |')
for b in backends:
    print(f"| {b.name} | {b.short_code} | {b.accepting_jobs} |")

Subcategories

Category Subcategory Short Code
Chemistry Molecular Ground State Estimation chem:mgse
Chemistry Other (Specify) chem:oth
Chemistry Quantum System Simulation chem:qss
Chemistry Variational Quantum Eigensolver (VQE) chem:vqe
Cryptography Discrete Logarithms crypto:dlog
Cryptography Hash Function Attacks crypto:hash
Cryptography Other (Specify) crypto:oth
Cryptography Shor's Factoring (RSA Cryptanalysis) crypto:shor
Finance Option Pricing fin:opt
Finance Other (Specify) fin:oth
Finance Portfolio Optimization fin:port
Finance Risk Analysis fin:risk
Graph and Network Analysis Graph Connectivity gna:con
Graph and Network Analysis Other (Specify) gna:oth
Graph and Network Analysis Pattern Matching gna:pat
Graph and Network Analysis Quantum Walks on Graphs gna:qwg
Machine Learning Other (Specify) ml:oth
Machine Learning Quantum Classification ml:qcl
Machine Learning Quantum Clustering ml:qcu
Machine Learning Quantum Recommendation Systems ml:qrs
Mathematics Differential Equations math:deq
Mathematics Hidden Subgroup Problems math:hsp
Mathematics Linear Systems (HHL Algorithm) math:hhl
Mathematics Other (Specify) math:oth
Optimization Adiabatic Optimization opt:adi
Optimization Constraint Satisfaction opt:csp
Optimization Other (Specify) opt:oth
Optimization Quantum Approximate Optimization Algorithm (QAOA) opt:qaoa
Other Other (Specify) oth:oth
Physics Hamiltonian Dynamics Simulation phys:hds
Physics Other (Specify) phys:oth
Physics Partition Functions phys:pfn
Physics Topological Invariants (e.g., Jones Polynomials) phys:tin

Note: This list may be modified as categories and subcategories are added or removed. For the most up-to-date list, run the following code:

cats = scheduler.get_job_categories().categories

print('| Category | Subcategory | Short Code |')
for cat in cats:
    subcats = scheduler.get_job_subcategories(cat.short_code).categories
    for subcat in subcats:
        print(f'| {cat.name} | {subcat.name} | {subcat.short_code} |')

FAQ

Q: How do I get results as JSON?
A: Use scheduler.download_job_output(job) — returns parsed object.

Q: Why does auto mode fail on some QPUs? A: "auto" selects the cheapest plan and priority (PUBLIC + STANDARD). If a backend only offers private execution, pass execution_plan="private" explicitly. Similarly, use queue_priority="priority" or "instant" for higher-priority queue access.

Q: Can I hide the public plan citation notice?
A: Setting OPENQUANTUM_HIDE_CITATION_NOTICE=true will omit the citation notice from output.

Metadata

Release files for openquantum-sdk 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openquantum-sdk 0.4.3
File Size Uploaded Provenance Actions
openquantum_sdk-0.4.3.tar.gz 45.7 kB Without provenance Details for openquantum_sdk-0.4.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for openquantum-sdk 0.4.3
File Interpreter ABI Platform Actions
openquantum_sdk-0.4.3-py3-none-any.whl Python 3 none any Details for openquantum_sdk-0.4.3-py3-none-any.whl

Total release size: 81.4 kB

Release files / openquantum_sdk-0.4.3.tar.gz

Download URL openquantum_sdk-0.4.3.tar.gz
Size 45.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4451c39f30da98caa44784f58b5ec004e54bb09a76d1abe0b644250d2b13f975
BLAKE2b-256 checksum
How to use checksums
a7624a265026c60e479a6323ffffa3a9d3a215dfb749fa41166deec0b1dc854e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / openquantum_sdk-0.4.3-py3-none-any.whl

Download URL openquantum_sdk-0.4.3-py3-none-any.whl
Size 35.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
011f34eded21256f6df4c2fb54a9ea0204370b084a0dd2999953a34cc6776ba0
BLAKE2b-256 checksum
How to use checksums
8890bf5d7ec9fb395048ab292e42503b42542ae8f81cb2d4b0a8ab1e5754dfcd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for openquantum-sdk 0.4.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page