Skip to main content

Python client for the QDash API

Project description

qdash.client README

qdash.client is a Python client for calling the QDash API.

  • services: domain logic such as authentication, retries, and response normalization
  • rest: low-level HTTP communication

This package follows the same approach as oqtopus-client, separating the transport layer from the service layer. For user-facing examples, see docs/user-guide/qdash-client.md.

Installation

Install the lightweight client package when only programmatic API access is needed.

pip install qdash-client

For development against this repository:

pip install ./src/qdash/client

The distribution name is qdash-client, but the Python import path is qdash.client.

Publishing

qdash-client is published from this repository with PyPI Trusted Publishing. Configure the qdash-client project on PyPI to trust this GitHub repository and the .github/workflows/publish-qdash-client.yml workflow.

Release tags use the qdash-client-v<version> format. Do not edit a package version in pyproject.toml; the package version is derived from the matching Git tag at build time.

git tag qdash-client-v<version>
git push origin qdash-client-v<version>

Minimal Quick Start

This is a minimal example using /chips, /metrics/config, and /task-results/timeseries.

from qdash.client import QDashClient

client = QDashClient()
try:
    chips = client.list_chips()
    print(chips.total)
    print([chip.chip_id for chip in chips.chips])

    metrics_config = client.get_metrics_config()
    print(metrics_config.keys())

    series = client.get_task_results_timeseries(
        chip_id="chip-001",
        parameter="t1",
        start_at="2026-06-01T00:00:00Z",
        end_at="2026-06-02T00:00:00Z",
    )
    print(series.data)
finally:
    client.close()

1. Public API

In most cases, you will use the following:

  • QDashClient
  • QDashConfig
  • Exception classes such as QDashApiError
from qdash.client import QDashClient, QDashConfig

2. Configuration

2.1 From Environment Variables

from qdash.client import QDashClient

client = QDashClient.from_env()

Main environment variables:

  • QDASH_BASE_URL
  • QDASH_API_TOKEN
  • QDASH_PROJECT_ID
  • QDASH_CF_ACCESS_CLIENT_ID
  • QDASH_CF_ACCESS_CLIENT_SECRET
  • QDASH_TIMEOUT_SECONDS
  • QDASH_RETRY_MAX_ATTEMPTS
  • QDASH_RETRY_BACKOFF_SECONDS
  • QDASH_RETRY_MAX_BACKOFF_SECONDS
  • QDASH_VERIFY_TLS
  • QDASH_PROXY
  • QDASH_USER_AGENT

For legacy username/password authentication, set:

  • QDASH_USERNAME
  • QDASH_PASSWORD_ENV
  • the environment variable named by QDASH_PASSWORD_ENV (defaults to QDASH_PASSWORD)

2.2 From a Configuration File

from qdash.client import QDashClient

client = QDashClient.from_profile("default")

If path is omitted:

  1. If XDG_CONFIG_HOME is set: $XDG_CONFIG_HOME/qdash/config.ini
  2. Otherwise: ~/.config/qdash/config.ini

Example configuration:

[default]
base_url = https://example.qdash/api
api_token = your-token
project_id = your-project-id
cf_access_client_id = your-cf-client-id
cf_access_client_secret = your-cf-client-secret
timeout_seconds = 30
retry_max_attempts = 3
retry_backoff_seconds = 0.2
retry_max_backoff_seconds = 5.0

For legacy username/password authentication from a config file, use username and password_env instead of api_token.

Save a profile to config.ini:

from qdash.client import QDashConfig

config = QDashConfig(
    base_url="https://example.qdash/api",
    api_token="your-token",
    cf_access_client_id="your-cf-client-id",
    cf_access_client_secret="your-cf-client-secret",
)
config.save(profile="prod")

The saved file is created with owner-only permissions (0600) because it can contain API tokens and Cloudflare Access secrets.

2.3 Automatic Loading

from qdash.client import QDashClient

# Loads config.ini by default
client = QDashClient()

3. Usage (Synchronous API)

3.1 List Chips

from qdash.client import QDashClient

client = QDashClient()
try:
    chips = client.list_chips()
    print([chip.chip_id for chip in chips.chips])
finally:
    client.close()

3.2 Default Chip

get_default_chip() returns the most recently installed active chip. If no chips are active, it falls back to the most recently installed chip returned by the API.

from qdash.client import QDashClient

client = QDashClient()
try:
    chip = client.get_default_chip()
    print(chip.chip_id)
finally:
    client.close()

Use get_default_chip_id() when an API call only needs the chip ID.

3.3 Time-Series Metrics

from qdash.client import QDashClient

client = QDashClient()
try:
    chip_id = client.get_default_chip_id()
    series = client.get_task_results_timeseries(
        chip_id=chip_id,
        parameter="t1",
        tag="calibration",
        start_at="2026-06-01T00:00:00Z",
        end_at="2026-06-08T00:00:00Z",
        qid="Q00",
    )
    print(series.data)
finally:
    client.close()

3.4 Agent-Friendly Read-Only Queries

The client exposes common read-only endpoints used by QDash agents and scripts:

from qdash.client import QDashClient

client = QDashClient.from_profile("local")
try:
    chip_id = client.get_default_chip_id()

    task_results = client.list_task_results(chip_id=chip_id, status="success", limit=20)
    q00 = client.get_chip_qubit(chip_id=chip_id, qid="Q00")
    latest_t1 = client.get_qubit_latest_task_results(chip_id=chip_id, task="t1")
    q00_history = client.get_qubit_task_history(
        chip_id=chip_id,
        qid="Q00",
        task="t1",
        date="20260625",
    )

    projects = client.list_projects()
    file_tree = client.get_files_tree()
    flow_source = client.get_file_content("flows/demo.py")
    git_status = client.get_git_status()
    issues = client.list_issues(limit=20)
    knowledge = client.list_issue_knowledge(status="approved", limit=20)
    task_knowledge = client.list_task_knowledge()
    flows = client.list_flows()
    templates = client.list_flow_templates()
    executions = client.list_executions(chip_id=chip_id, limit=20)
    reviews = client.list_task_result_ai_reviews(chip_id=chip_id, limit=20)
    provenance = client.get_provenance_stats()

    print(task_results.total, q00.qid, latest_t1.task_name, q00_history.name)
    print(projects.total, len(file_tree), flow_source.get("path"), git_status, len(issues.issues))
    print(len(knowledge.items), len(task_knowledge.items), len(flows.flows), len(templates))
    print(len(executions.executions), reviews.total)
    print(provenance.total_entities)
finally:
    client.close()

Available read-only helpers include:

  • Chips: list_chips(), get_default_chip(), get_default_chip_id(), list_chip_qubits(), get_chip_qubit(), list_chip_couplings(), get_chip_coupling()
  • Task results: list_task_results(), get_qubit_latest_task_results(), get_qubit_task_history(), get_coupling_latest_task_results(), get_coupling_task_history(), get_task_result(), get_task_note(), list_task_result_issues(), list_task_result_ai_reviews(), list_task_result_ai_review_runs(), get_task_result_ai_review_run()
  • Tasks and task knowledge: list_tasks(), list_task_knowledge(), get_task_knowledge(), get_task_knowledge_markdown()
  • Projects and files: list_projects(), get_project(), get_files_tree(), get_file_content(), get_git_status()
  • Issues and knowledge: list_issues(), get_issue(), list_issue_knowledge(), get_issue_knowledge()
  • Flows and executions: list_flows(), get_flow(), list_executions(), get_execution(), list_flow_templates(), get_flow_template(), list_flow_helper_files(), get_flow_helper_file()
  • Provenance: get_provenance_entity(), get_provenance_lineage(), get_provenance_impact(), get_provenance_history(), get_provenance_stats(), get_provenance_changes()

3.5 Explicit Write And Operational Queries

Write helpers use the same profile, authentication, project headers, retries, and response validation as read-only helpers. Agents should ask for user confirmation before calling methods that mutate files, trigger executions, change issue status, push/pull git state, or alter task results.

from qdash.client import QDashClient

client = QDashClient.from_profile("local")
try:
    client.save_file_content(path="flows/demo.py", content="def demo(): pass")
    client.validate_file_content(content="def demo(): pass", file_type="flow")
    client.git_push_config(commit_message="Update demo flow")

    flow = client.save_flow(name="demo", code="def demo(): pass", chip_id="chip-001")
    execution = client.execute_flow(flow.name, parameters={"shots": 100})
    client.upsert_task_note("task-001", content="Reviewed by operator")
    client.set_task_result_excluded("task-001", excluded=True, reason="bad fit")

    print(flow.file_path, execution.execution_id)
finally:
    client.close()

Available write and operational helpers include:

  • Files and git: save_file_content(), validate_file_content(), git_pull_config(), git_push_config()
  • Flows and executions: save_flow(), execute_flow(), schedule_flow(), cancel_execution(), re_execute_execution()
  • Task results: upsert_task_note(), delete_task_note(), set_task_result_excluded(), re_execute_task_result(), create_task_result_issue()
  • Issues and knowledge: update_issue(), close_issue(), reopen_issue(), update_issue_knowledge(), approve_issue_knowledge(), reject_issue_knowledge(), extract_issue_knowledge()

3.6 Metrics Configuration

from qdash.client import QDashClient

client = QDashClient()
try:
    config = client.get_metrics_config()
    print(config.get("qubit_metrics", {}).keys())
    print(config.get("coupling_metrics", {}).keys())
finally:
    client.close()

4. Usage (Asynchronous API)

import asyncio
from qdash.client import QDashClient

async def main() -> None:
    client = QDashClient()
    try:
        chips = await client.list_chips_async()
        print([chip.chip_id for chip in chips.chips])

        metrics_config = await client.get_metrics_config_async()
        print(metrics_config.get("qubit_metrics", {}).keys())

        series = await client.get_task_results_timeseries_async(
            chip_id="chip-001",
            parameter="t1",
            start_at="2026-06-01T00:00:00Z",
            end_at="2026-06-02T00:00:00Z",
        )
        print(series.data)
    finally:
        client.close()

asyncio.run(main())

5. Error Handling

Main exceptions:

  • QDashApiError (base class)
  • QDashAuthError (missing or invalid authentication)
  • QDashNotFoundError (404)
  • QDashValidationError (422)
  • QDashTransportError (transport errors, timeouts, or other HTTP statuses)
from qdash.client import QDashClient, QDashApiError

client = QDashClient()
try:
    print(client.list_chips().chips)
except QDashApiError as exc:
    print(exc.status_code, exc)
finally:
    client.close()

6. Exporter Helper Functionality

QDashClient provides helper methods for exporters.

  • normalize_chip_metrics(chip_id, payload)

This method converts a QDash API response into a list of NormalizedMetricRecord objects that are easier for exporters to consume.

7. Using the Low-Level REST Client Directly

In most cases, using QDashClient is recommended.

If you need direct access to the low-level API, you can use qdash.client.rest.

from qdash.client.rest import ApiClient, Configuration

cfg = Configuration(host="https://example.qdash/api")
rest_client = ApiClient(cfg)

try:
    resp = rest_client.request("GET", "/chips")
    print(resp.status_code, resp.data)
finally:
    rest_client.close()

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

qdash_client-0.1.6.tar.gz (41.0 kB view details)

Uploaded Source

Built Distribution

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

qdash_client-0.1.6-py3-none-any.whl (43.3 kB view details)

Uploaded Python 3

File details

Details for the file qdash_client-0.1.6.tar.gz.

File metadata

  • Download URL: qdash_client-0.1.6.tar.gz
  • Upload date:
  • Size: 41.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qdash_client-0.1.6.tar.gz
Algorithm Hash digest
SHA256 aa9dd5b532e81c90cef666bc2b749be53d5d9c7469d447550a12d0037a1e8fbe
MD5 eca1056927200834a80dc3426e0865a2
BLAKE2b-256 c2747239ed718104f24374d91c9e6885d34279e70131bcd3be1b1bc8cfa56ded

See more details on using hashes here.

Provenance

The following attestation bundles were made for qdash_client-0.1.6.tar.gz:

Publisher: publish-qdash-client.yml on oqtopus-team/qdash

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qdash_client-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: qdash_client-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 43.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qdash_client-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 a58f3b0406e6884fc23bdb90cb3a541d087f3b00fe951113570d5441ec9166bb
MD5 32cd34491b101768cb83a5166f76583b
BLAKE2b-256 40620088dfc7dea844d2d0239ade0ea0b4b070cc6c8cf6e5ccb4a7907b16b844

See more details on using hashes here.

Provenance

The following attestation bundles were made for qdash_client-0.1.6-py3-none-any.whl:

Publisher: publish-qdash-client.yml on oqtopus-team/qdash

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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