This release is a pre-release and may not be stable for production use.
cqlib-tianyan
Python bindings for the Tianyan quantum cloud platform client.
Overview
This package provides synchronous Python access to the Tianyan quantum computing cloud platform, allowing users to:
- Authenticate with API keys
- Discover available quantum backends
- Submit quantum circuits (QCIS format)
- Retrieve execution results with readout error mitigation
All blocking operations release the GIL, making the library safe for use in multi-threaded Python applications.
Installation
From Source (Development)
# Install maturin if not already installed
pip install maturin
# Build and install the package
maturin develop
Production Build
maturin build --release
pip install target/wheels/*.whl
Quick Start
from cqlib_tianyan import TianyanPlatform
# Authenticate with your API key
platform = TianyanPlatform.login("your_api_key")
# List available backends
backends = platform.list_backends()
for backend in backends:
print(f"{backend.name}: {backend.status}")
# Get a specific backend
backend = platform.get_backend("tianyan-287")
print(f"Physical qubits: {backend.num_qubits()}")
# Submit a circuit
task = backend.run(["H Q1\nM Q1"], shots=1000)
# Wait for results
results = task.wait(timeout=120.0)
for result in results:
print(f"Task ID: {result.task_id}")
print(f"Counts: {result.counts}")
print(f"Probabilities: {result.probabilities}")
API Reference
Core Classes
TianyanPlatform
The main entry point for interacting with the Tianyan platform.
# Login with API key
platform = TianyanPlatform.login(
api_key="your_key",
domain="qc.zdxlz.com", # Optional
save_credentials=True, # Optional, default: True
auto_refresh=True, # Optional, default: True
)
# Load from saved credentials
platform = TianyanPlatform.from_credentials()
# List all backends
backends = platform.list_backends()
# Get specific backend
backend = platform.get_backend("device_name")
# Submit circuits directly
task = platform.submit(
circuits=["H Q1\nM Q1"],
shots=1000,
device_name="tianyan-287"
)
TianyanBackend
Represents a quantum computing backend.
Only superconducting devices and simulators can submit tasks. Photonic and ion-trap
devices fail before submission. Configuration access (device_config() and
num_qubits()) and readout calibration require a superconducting device.
In "auto" mode, simulators return raw counts without downloading configuration;
superconducting devices apply calibration when data is available and at most 14
qubits are measured. Explicit "enabled" mode fails before submission on any
non-superconducting device. "disabled" always returns raw counts.
# Backend properties
backend.name # Device identifier
backend.display_name # Human-readable name
backend.device_type # DeviceType enum
backend.status # DeviceStatus enum
backend.toll # DeviceToll enum (free/paid)
if backend.device_type == "superconducting":
backend.num_qubits() # Physical qubit count (loads config on first use)
# Check availability
if backend.is_available() and backend.device_type.value in ("superconducting", "simulator"):
# Submit circuits
task = backend.run(circuits=["H Q1\nM Q1"], shots=1000)
# Raw execution (no calibration)
task = backend.run(circuits=["H Q1\nM Q1"], shots=1000, calibration_mode="disabled")
# With explicit calibration mode
task = backend.run(
circuits=["H Q1\nM Q1"],
shots=1000,
calibration_mode="disabled" # "auto", "enabled", "disabled"
)
# Get device configuration
if backend.device_type == "superconducting":
device = backend.device_config() # Returns cqlib.device.Device
run(circuits, shots, *, calibration_mode="auto") accepts a string or a
CalibrationMode object. platform.submit() accepts the same keyword-only
option. Each call submits a new task. run_raw() and run_with_mode() remain
deprecated aliases and emit DeprecationWarning.
TaskHandle
Represents a batch of submitted circuits.
wait() and wait_raw() take timeout and poll_interval in seconds, with
defaults of 120.0 and 5.0. Both methods can be called without arguments.
# Task properties
task.task_ids # List of platform-assigned task IDs
task.device_name # Backend name
task.shots # Number of shots
task.submitted_at # ISO 8601 timestamp
# Non-blocking status check
results = task.status() # Returns completed results only
# Blocking wait for all results
results = task.wait(
timeout=120.0,
poll_interval=5.0
)
# Wait for raw results
results = task.wait_raw() # timeout=120.0, poll_interval=5.0 (seconds)
TianyanConfig
Configuration for the platform client.
config = TianyanConfig(
domain="qc.zdxlz.com",
save_credentials=True,
auto_refresh=True,
credentials_path="~/.cqlib/tianyan/credentials.json"
)
Enums
from cqlib_tianyan import DeviceStatus, DeviceToll, DeviceType, CalibrationMode
# DeviceStatus values: "running", "calibration", "under_maintenance", "offline", "upgrading", "unknown"
# DeviceToll values: "free", "paid", "unknown"
# DeviceType values: "superconducting", "photonic", "ion_trap", "simulator"
# CalibrationMode values: "auto", "enabled", "disabled"
Read backend.device_type.value, or compare directly with a string, such as
backend.device_type == "simulator".
| Device type | .value |
Devices |
|---|---|---|
| Simulator | simulator |
tianyan_sw, tianyan_s, tianyan_tn, tianyan_tnn, tianyan_sa, tianyan_swn |
| Photonic | photonic |
tianyan-p2000 |
| Superconducting | superconducting |
tianyan176, tianyan176-2, tianyan24, tianyan504, tianyan-287, tianyan-294 |
Exception Handling
from cqlib_tianyan import TianyanError
try:
platform = TianyanPlatform.login("invalid_key")
except Exception as e:
# Handle authentication failure
print(f"Login failed: {e}")
Note: In abi3 mode, TianyanError cannot be caught by type. Catch Exception instead.
Testing
Test Structure
tests/
├── conftest.py # Pytest configuration and fixtures
└── test_cqlib_tianyan.py # Main test file
Environment Variables
| Variable | Required | Description |
|---|---|---|
TIANYAN_API_KEY |
For integration tests | Your Tianyan platform API key |
TIANYAN_DOMAIN |
Optional | Custom domain (defaults to qc.zdxlz.com) |
TIANYAN_DEVICE |
Optional | Target device name (e.g., "tianyan-287") |
Running Tests
# Run all tests (requires API key)
TIANYAN_API_KEY="your_key" pytest tests/ -v
# Run with specific device
TIANYAN_API_KEY="your_key" TIANYAN_DEVICE="tianyan-287" pytest tests/ -v
# Run only unit tests (no API key required)
pytest tests/ -v -m "not integration"
# Run integration tests only
TIANYAN_API_KEY="your_key" pytest tests/ -v -m integration
# Include slow tests (long timeouts)
TIANYAN_API_KEY="your_key" pytest tests/ -v --run-slow
# Run specific test class
TIANYAN_API_KEY="your_key" pytest tests/test_cqlib_tianyan.py::TestCircuitSubmission -v
Test Markers
| Marker | Description |
|---|---|
integration |
Requires API access and network connectivity |
slow |
Long-running tests (waits for circuit execution) |
Technical Details
Architecture
This package is built with:
- PyO3: Rust-Python bindings
- Maturin: Build tool for Python-Rust hybrid projects
- abi3: Stable Python ABI (supports Python 3.10+)
Module Structure
crates/binding-python/
├── Cargo.toml # Rust package manifest
├── pyproject.toml # Python package configuration
├── src/
│ ├── lib.rs # Module initialization
│ ├── error.rs # Exception types
│ ├── config.rs # TianyanConfig bindings
│ ├── platform.rs # TianyanPlatform bindings
│ ├── backend.rs # TianyanBackend bindings
│ └── task.rs # TaskHandle bindings
├── cqlib_tianyan/
│ ├── __init__.py # Python package entry
│ ├── __init__.pyi # Type stubs
│ └── py.typed # PEP 561 marker
└── tests/
├── conftest.py # Pytest configuration
└── test_cqlib_tianyan.py # Test suite
Known Limitations
-
ABI3 Mode: Due to
abi3-py310feature:TianyanErrorcannot inherit fromRuntimeErrorTianyanErrorcannot be instantiated directly in Python- Exception catching must use
except Exception:instead ofexcept TianyanError:
-
GIL Release: Long-running operations (
wait(),wait_raw()) release the GIL to allow other Python threads to run.
Dependencies
- Python >= 3.10
cqlib>=2.0.0b1(installed automatically) fordevice_config()andExecutionResultconversion. The classic PyPIcqlib 1.3.xis not compatible; it does not providecqlib.deviceorcqlib.circuit.cqlib-core>=0.1.0-beta.1(Rust workspace dependency from crates.io)cqlib-tianyan(Rust workspace dependency)
License
Licensed under the Apache License, Version 2.0.
Copyright (c) 2026 China Telecom Quantum Group
Metadata
Release files for cqlib-tianyan 0.1.0b2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| cqlib_tianyan-0.1.0b2-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| cqlib_tianyan-0.1.0b2-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| cqlib_tianyan-0.1.0b2-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| cqlib_tianyan-0.1.0b2-cp310-abi3-macosx_11_0_x86_64.whl | CPython 3.10 | abi3 | macOS 11.0+ x86-64 | Details |
| cqlib_tianyan-0.1.0b2-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 10.6 MB
Release files / cqlib_tianyan-0.1.0b2-cp310-abi3-win_amd64.whl
| Download URL | cqlib_tianyan-0.1.0b2-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
c7b8b5fcbb23d85fbd61273937acc97a5173ad29c26981b95c33c4c7e5e552f9
|
|
BLAKE2b-256 checksum How to use checksums |
d0b181726ace04ac991c962d4b4b3acb61f8a5646744341626504233f2570b43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / cqlib_tianyan-0.1.0b2-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | cqlib_tianyan-0.1.0b2-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 3.2 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
ab884571589e41ef9652c39e9cf7bf2631a6844c49b6f973d433903b81b47c3c
|
|
BLAKE2b-256 checksum How to use checksums |
34e3ca067685c1ea1fbc1270a4250f70dc25ccad4089ed2ebfd3a103b8137ffa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / cqlib_tianyan-0.1.0b2-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | cqlib_tianyan-0.1.0b2-cp310-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
634992a697e3143e380548ece5c51faede5616506c915374b2c62ab7986fbc6d
|
|
BLAKE2b-256 checksum How to use checksums |
94e0d4fece1e91094307eb14bc5a91e766ac221861ef0022fe4694ce26cba910
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / cqlib_tianyan-0.1.0b2-cp310-abi3-macosx_11_0_x86_64.whl
| Download URL | cqlib_tianyan-0.1.0b2-cp310-abi3-macosx_11_0_x86_64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
860b9cc2c066051c265c22f6ad6fc2724f192bcd0ecef76094599e08442de880
|
|
BLAKE2b-256 checksum How to use checksums |
3662692b6dd67bf5d63ab4ea162c5c04e5eaca3292fdaf7d7d5ef4bdc95418c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / cqlib_tianyan-0.1.0b2-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | cqlib_tianyan-0.1.0b2-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d94bbf32c8cf31e57fd7ee6612a45e9fb5f19b8589105902297fbc8d9c60ce69
|
|
BLAKE2b-256 checksum How to use checksums |
eceddc3cf81c1d34003fd1cb65803ed29e6111c39e24d67874d7a8280f48069c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|