Skip to main content

Commutator Studios Python SDK

PyPI Version Python Versions License

Commutator SDK is the official Python client for the Commutator Studios quantum ecosystem. It provides a seamless, developer-friendly interface to integrate quantum workloads, optimization engines, and identity management natively into your Python tech stack.

By connecting to the Centralized API Gateway (commutator.app), this SDK handles authentication, rate-limiting, and billing checks automatically, allowing you to focus on building quantum-accelerated applications.


Features

  • Quantum Fleet Management: Discover, list, and check the status of available quantum backends (e.g., ibm_berlin, ibmq_qasm_simulator). Automatically synchronizes hardware catalog using the authenticated user's quantum provider credentials.
  • Hardware & Algorithmic Recommendations: Interface directly with cs-optimizer to get smart recommendations for hardware and optimization levels (e.g., VQE) before you run your circuits.
  • Job Execution & Polling: Submit quantum circuits, execute jobs on actual quantum hardware, and download results natively into Python objects.
  • Standardized Error Handling: Detailed, structured exceptions (APIError, ValidationError, AuthenticationError) for predictable and easy debugging.
  • ...and more!

Installation

The SDK requires Python 3.11+. You can install it directly from PyPI using pip:

pip install commutator-sdk

Install the optional Qiskit interoperability layer when constructing jobs from native QuantumCircuit and SparsePauliOp objects:

pip install "commutator-sdk[qiskit]"

Quick Start

Here is a simple example showing how to authenticate, create a job, execute a circuit, and fetch the results.

1. Authentication

You can authenticate using your API Key or Username/Password.

from commutator.client import CommutatorClient

# Initialize the client (Environment is auto-detected)
client = CommutatorClient(api_key="your_api_key_here")

2. Submitting a Quantum Job

Submit your quantum circuit JSON and execute it on a selected backend.

import time

from commutator import (
    ClassicalOptimizer,
    CommutatorClient,
    CSAlgorithmName,
    CSRunOptions,
    CSVQEOptions,
)

client = CommutatorClient()  # Reads COMMUTATOR_API_KEY
backend = client.backends.get("ibm_berlin")

# 1. Create the job with a built-in algorithm enum.
job = client.jobs.create(
    name="My First VQE Run",
    algorithm=CSAlgorithmName.VQE1,
    file_path="circuit.json"
)
print(f"Job created successfully: {job.id}")

# 2. Persist algorithm controls (e.g. COBYLA, max_iterations, convergence) and submit execution settings
job = job.run(
    execution_options=CSRunOptions(backend=backend, optimization_level=3),
    algorithm_options=CSVQEOptions(max_iterations=5, convergence=0.005),
)
while not job.done:
    time.sleep(5)
    job = job.refresh()
print(job.results())

3. Optimizer Recommendations

Not sure which backend or optimization level to use? Ask the Recommendation Engine!

job = job.recommend(
    target_backends=[backend, "ibm_brisbane"],  # CSBackend objects and slugs are accepted.
    timeout=300,
)
print(job.recommendations_table())
execution_options = job.best_recommendation(
    backend=backend,
    dynamic_decoupling=True,
)
if execution_options is None:
    raise RuntimeError("No completed recommendation matches those filters")

# recommendations() returns every completed CSRunOptions choice and always
# reads current platform state without starting another recommendation run.
other_options = job.recommendations()[1]
job = job.run(
    execution_options=execution_options,
    algorithm_options=CSVQEOptions(max_iterations=100, convergence=0.001),
)

Error Handling & Exception Reference

When executing quantum simulation jobs, the SDK automatically inspects the API response errorCode and raises typed Python exceptions providing human-readable diagnostic remedies:

from commutator.client import CommutatorClient
from commutator.exceptions import (
    SimulationOOMError,
    SimulationTimeoutError,
    ProviderAuthenticationError,
    JobFailedError
)

client = CommutatorClient(api_key="your_api_key")

try:
    job_details = client.jobs.get(job_id="5bacd027-267d-4c8e-94c4-5348c48880b3")
except SimulationOOMError as e:
    print(f"❌ Memory Error [{e.error_code}]: {e.message}")
    print(f"💡 Actionable Remedy: {e.remedy}")
except SimulationTimeoutError as e:
    print(f"⏱️ Job Timed Out [{e.error_code}]: {e.message}")
    print(f"💡 Actionable Remedy: {e.remedy}")
except JobFailedError as e:
    print(f"⚠️ Job Execution Failed [{e.error_code}]: {e.message}")

Supported Exception Mapping

API errorCode Enum Raised SDK Exception Class Python Import Path
SIMULATION_OOM SimulationOOMError from commutator.exceptions import SimulationOOMError
SIMULATION_TIMEOUT SimulationTimeoutError from commutator.exceptions import SimulationTimeoutError
PROVIDER_AUTH_FAILED ProviderAuthenticationError from commutator.exceptions import ProviderAuthenticationError
OPTIMIZATION_DIVERGED OptimizationDivergedError from commutator.exceptions import OptimizationDivergedError
Fallback / System Faults JobFailedError from commutator.exceptions import JobFailedError

Advanced Usage

Backend and job resources

The SDK returns validated Commutator Studios resource objects by default:

import time

from commutator import (
    CommutatorClient,
    CSAlgorithm,
    CSAlgorithmName,
    CSBackend,
    CSBackends,
    CSJob,
    CSJobs,
    CSProvider,
    CSRunOptions,
    CSVQEAlgorithm,
    CSVQEOptions,
)

client = CommutatorClient()  # Reads COMMUTATOR_API_KEY
cs_backends: CSBackends = client.backends
algorithms: list[CSAlgorithm] = client.jobs.list_algorithms()

backend: CSBackend = cs_backends.get("ibm_fez")
job: CSJob = client.jobs.create(
    name="My first VQE run",
    algorithm=CSAlgorithmName.VQE1,
    file_path="circuit.json",
)
job = job.run(
    execution_options=CSRunOptions(
        backend=backend,
        optimization_level=2,
        predicted_shots=1024,
    ),
    algorithm_options=CSVQEOptions(max_iterations=100, convergence=0.001),
)
while not job.done:
    time.sleep(5)
    job = job.refresh()
result = job.results()

CSBackends supports listing, local filters, lookup, refresh, discovery, and explicit enable/disable operations:

available = client.backends.list(
    provider=CSProvider.IBM,
    enabled=True,
    operational=True,
    min_qubits=100,
)
backend = backend.refresh()
backend = backend.disable()
backend = backend.enable()
backend = client.backends.disable("ibm_fez")
backend = client.backends.enable("ibm_fez")

CSJobs supports create, get, list, keyword search and destructive deletion. list_algorithms() returns validated CSAlgorithm objects with id, name, full_name and is_available fields. Algorithm-specific entries use subclasses: VQE catalog rows are CSVQEAlgorithm objects, while algorithms without a typed SDK contract remain CSAlgorithm objects. create() accepts one of these objects, a CSAlgorithmName enum member, or a string identifier.

The public types have distinct responsibilities:

Type Responsibility
CSAlgorithm / CSVQEAlgorithm Catalog metadata / VQE input construction, options and result parsing
CSVQEInput Ansatz, Hamiltonian and optimizer initial point
CSVQEOptions Classical optimization settings
CSRunOptions Backend and quantum execution settings
CSVQEResult Scientific results and legacy artifact compatibility

Implementation lives in algorithms.py, inputs.py, and results.py, with resource snapshots in models.py. Existing top-level and commutator.models imports remain supported. Algorithm metadata supplied at creation or read by list_algorithms() remains available to subsequent jobs on that client. Without catalog metadata, the SDK uses the legacy VQE* identifier fallback.

For VQE, the selected algorithm can construct the matching input model directly from Qiskit objects:

algorithm: CSVQEAlgorithm = next(
    item
    for item in client.jobs.list_algorithms()
    if isinstance(item, CSVQEAlgorithm) and item.id == "VQE1"
)
vqe_input = algorithm.create_input(
    circuit=ansatz,
    hamiltonian=hamiltonian,
    # These values are the optimizer's initial point. Omit them to generate
    # and retain one random point for recommendations and final execution.
    parameters=[0.1, -0.2],
)
job = client.jobs.create(name="Hydrogen VQE", algorithm=algorithm, input=vqe_input)

file_path="circuit.json" remains supported. Provide either input or file_path, but not both. The typed route validates Qiskit object types, qubit counts, finite real Hamiltonian coefficients and the number of initial parameter values before creating the job. It generates omitted parameters once when the input object is constructed; reusing that input reuses the same initial point. OpenQASM export uses ordered parameter identifiers so engine import preserves positional binding. parameter_names retains the original circuit names in that same order. A named result binds values by name and rejects a mismatched circuit. The legacy file route checks the JSON container only; it does not yet provide the typed route's semantic validation or initialization.

CSJob supports refresh(), recommend(), recommendations(), recommendations_table(), filtered best_recommendation(), run(), results() and get_backend(). recommend() returns a fresh snapshot of the same remote job, and both recommendation accessors return CSRunOptions. Each bound recommendations() call reads the latest completed rows from the platform without submitting new optimizer work, so repeated calls can reveal a growing table without restarting it. Call recommend() explicitly to start generation. Job names cannot currently be changed after creation because the platform execution endpoint does not update the circuit name. Resource methods return new snapshots, so assign their return values.

best_recommendation() accepts optional backend, optimization_level, and dynamic_decoupling filters and returns None when no completed option matches. recommendations_table() produces a dependency-free ASCII table ordered by predicted score.

CSRunOptions holds only backend and quantum execution settings. It validates optimization level (0–3), booleans and positive shot counts. with_overrides() makes a validated copy when you want to adjust a recommended execution option. CSAlgorithmOptions is the base for algorithm-specific settings; CSVQEOptions provides positive max_iterations and convergence controls and an optional optimizer (ClassicalOptimizer.COBYLA or ClassicalOptimizer.SIMPLEX; the strings "cobyla" and "simplex" are also accepted at runtime). An unset optimizer is omitted from requests so it does not replace a stored choice. Pass these options to job.run(algorithm_options=...); the SDK persists them before it submits execution_options. job.algorithm_options returns the effective algorithm-specific model (CSVQEOptions for a VQE job). The current platform PATCH dispatch does not forward stored convergence to the optimizer, so saving it does not yet guarantee it controls execution. This needs the separate service-side algorithm-options change. The two writes are not atomic: if dispatch fails after saving settings, refresh the job to inspect its current state before retrying. If future recommendation rows contain VQE controls, they fill only fields that are unset on the job; explicitly stored values win.

For VQE jobs, job.results() returns CSVQEResult. It accepts both current partial/list artifacts and the planned structured result, so absent fields such as optimal_parameters, iterations, or convergence_reason remain None instead of breaking older jobs. When parameter names and optimal values are available, use result.optimal_parameter_map or result.bind_optimal_parameters(circuit). Unknown explicit result schema versions require an SDK update; additive fields within the supported version remain available. Full optimizer metrics and optimal parameters still depend on the service emitting the structured result contract. Additional service options require the explicit experimental={...} escape hatch and cannot replace validated options, identity, backend or status.

Use job.refresh() for read-only status polling and stop when job.done is true. GET requests retain bounded rate-limit retries, while mutating requests are not replayed automatically. COMMUTATOR_TIMEOUT controls the request timeout and defaults to 300 seconds.

There is no CSJob.cancel() yet. The legacy client.jobs.cancel() aliases the destructive job-and-artifact deletion endpoint, so it is not exposed as a resource convenience method.

Resource snapshots retain additive response fields and support Pydantic serialization. model_dump(mode="json", by_alias=True) uses API field names. A model loaded from JSON is detached; retrieve it through the client before calling a network method. Resources from another client are rejected before submission.

Backend, RunOptions, BackendsModule, JobsModule and client.fleet remain as compatibility aliases. Explicit list_raw() methods are available for integrations that still need the original response dictionaries.

Interactive walkthrough

Open example.ipynb from the python directory using the SDK virtual environment. The notebook has short, sequential examples for backend selection, fleet management, job creation, execution, polling and results. It uses a local sample API by default; its authentication cell explains how to switch to staging for a real run.

Install the checkout and notebook dependencies first:

cd python
.venv/bin/python -m pip install -e . -r requirements-dev.txt

The development dependencies include Qiskit and its OpenQASM 3 importer so the VQE contract tests always run under python -m pytest tests/. These remain optional for SDK users; the base package does not require Qiskit.

For comprehensive documentation, including detailed API reference, Identity Management (list_api_keys, get_audit_logs), and advanced configuration options, please refer to the official Commutator Studios Documentation.

License

Copyright © 2026 Commutator Studios GmbH. All rights reserved.

Metadata

Release files for commutator-sdk 0.3.0

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

Source distribution (sdist)

Source distribution for commutator-sdk 0.3.0
File Size Uploaded Provenance Actions
commutator_sdk-0.3.0.tar.gz 53.2 kB Without provenance Details for commutator_sdk-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for commutator-sdk 0.3.0
File Interpreter ABI Platform Actions
commutator_sdk-0.3.0-py3-none-any.whl Python 3 none any Details for commutator_sdk-0.3.0-py3-none-any.whl

Total release size: 91.3 kB

Release files / commutator_sdk-0.3.0.tar.gz

Download URL commutator_sdk-0.3.0.tar.gz
Size 53.2 kB
Tags Source
SHA-256 checksum
How to use checksums
795c6f1e46616f2662484f39f7f20c81760747a3c54f170d345c0adbe90492c8
BLAKE2b-256 checksum
How to use checksums
f77895675428696f3132cce556fa47af6be7abdaa0f5ded422163f7d404c2e93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / commutator_sdk-0.3.0-py3-none-any.whl

Download URL commutator_sdk-0.3.0-py3-none-any.whl
Size 38.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2a5de51b832e856481109d9b96276a8833a9548e6c083752aff16cad83972d53
BLAKE2b-256 checksum
How to use checksums
ea53dc29853101ea2296c6c1cf55129796a2529dcb66e2f004cbd8cb53977917
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.15

Security for commutator-sdk 0.3.0

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