qdash.client README
qdash.client is a Python client for calling the QDash API.
services: domain logic such as authentication, retries, and response normalizationrest: 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 ./clients/python
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.
QDash uses a single v<version> release tag for the application and its clients. Do not edit a
package version in pyproject.toml; the package version is derived from that Git tag at build
time. Creating the tag also publishes the TypeScript client and creates the GitHub Release.
git tag v<version>
git push origin 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:
QDashClientQDashConfig- 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_URLQDASH_API_TOKENQDASH_PROJECT_IDQDASH_CF_ACCESS_CLIENT_IDQDASH_CF_ACCESS_CLIENT_SECRETQDASH_TIMEOUT_SECONDSQDASH_RETRY_MAX_ATTEMPTSQDASH_RETRY_BACKOFF_SECONDSQDASH_RETRY_MAX_BACKOFF_SECONDSQDASH_VERIFY_TLSQDASH_PROXYQDASH_USER_AGENT
For legacy username/password authentication, set:
QDASH_USERNAMEQDASH_PASSWORD_ENV- the environment variable named by
QDASH_PASSWORD_ENV(defaults toQDASH_PASSWORD)
2.2 From a Configuration File
from qdash.client import QDashClient
client = QDashClient.from_profile("default")
If path is omitted:
- If
XDG_CONFIG_HOMEis set:$XDG_CONFIG_HOME/qdash/config.ini - 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()
Metadata
Release files for qdash-client 1.8.39
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qdash_client-1.8.39.tar.gz | 69.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qdash_client-1.8.39-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 125.6 kB
Release files / qdash_client-1.8.39.tar.gz
| Download URL | qdash_client-1.8.39.tar.gz |
|---|---|
| Size | 69.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9d6684ef8b0b40bc81517707fbebc381b4a80c5213c70162bc0693cdd09b8f02
|
|
BLAKE2b-256 checksum How to use checksums |
450f069a4dc2115e094b379ed55908fbbdd86e43a4bf7ac2c9b7a69be056d065
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.
Transparency logRelease files / qdash_client-1.8.39-py3-none-any.whl
| Download URL | qdash_client-1.8.39-py3-none-any.whl |
|---|---|
| Size | 56.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
606aae5b8b7718d49db405db6e2e36a3c1795da0c74a3c4818eb1aa4c80ce30c
|
|
BLAKE2b-256 checksum How to use checksums |
ca23cfc8562fa6842d7a1d487e47dfc5d6b4e8092c2522516bc7eaf263433577
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.
Transparency log