Skip to content

Client API

Experiment scripts use LabClient (or AsyncLabClient) to talk to Central, and a driver package's facades (such as labnet_sim.SimulatedWavemeter) to use a device. Everything here is importable from labnet directly: from labnet import LabClient, LabClientError.

lab_client

Synchronous and async-first clients for the versioned Central API.

LabClient

LabClient(server_url: str, api_key: str, timeout_seconds: float = 10.0, authenticate_on_start: bool = True, *, ca_file: str | Path | None = None, transport: BaseTransport | None = None)

Blocking Central client for scripts and synchronous device wrappers.

from_env classmethod

from_env(env_file: str | Path | None = None, **options: Any) -> 'LabClient'

Connect using LABNET_SERVER_URL, LABNET_API_KEY, and LABNET_CA_FILE.

Values come from the process environment, then from env_file, the file named by LABNET_ENV_FILE, or ./.env, in that order.

health

health() -> dict[str, Any]

Return Central readiness (compatibility alias for health_ready).

list_lab_pcs

list_lab_pcs() -> list[LabPCInfo]

Every Lab PC registered with Central, online or not, with its devices.

AsyncLabClient

AsyncLabClient(server_url: str, api_key: str, timeout_seconds: float = 10.0, authenticate_on_start: bool = True, *, ca_file: str | Path | None = None, transport: AsyncBaseTransport | None = None)

Async-first Central client with managed lease/device context cleanup.

from_env classmethod

from_env(env_file: str | Path | None = None, **options: Any) -> 'AsyncLabClient'

Connect using LABNET_SERVER_URL, LABNET_API_KEY, and LABNET_CA_FILE.

Values come from the process environment, then from env_file, the file named by LABNET_ENV_FILE, or ./.env, in that order.

health async

health() -> dict[str, Any]

Return Central readiness (compatibility alias for health_ready).

list_lab_pcs async

list_lab_pcs() -> list[LabPCInfo]

Every Lab PC registered with Central, online or not, with its devices.

acquire_device async

acquire_device(contract: Any, device_id: str | None = None, *, duration_seconds: int = DEFAULT_LEASE_DURATION_SECONDS, auto_renew: bool = True, renewal_interval_seconds: float = DEFAULT_RENEWAL_INTERVAL_SECONDS, idempotency_key: str | None = None, tls: GrpcTlsConfig | None = None, connection_timeout_seconds: float = 10.0, default_rpc_timeout_seconds: float = 10.0) -> AsyncContractDeviceClient

Lease any generated device contract using shared async plumbing.

Results and descriptions

models

Typed models shared by the Central HTTP and device gRPC clients.

EndpointDescriptor dataclass

EndpointDescriptor(transport: str, target: str, api_version: str, secure: bool, tls_server_name: str | None = None, attributes: dict[str, Any] = dict())

A versioned direct device-service endpoint returned by Central.

DeviceInfo dataclass

DeviceInfo(device_id: str, manager_id: str, endpoint: EndpointDescriptor, device_type: str = '', runtime_state: str = 'unknown', availability: str = 'unknown', status_text: str = '', last_seen: datetime | None = None, metadata: dict[str, Any] = dict(), effective_available: bool = False, allocation_state: str = 'unknown')

type property

type: str

The v1 wire field is type; device_type is clearer in Python.

status property

status: str

Compatibility alias for callers migrating from the legacy client.

LabPCInfo dataclass

LabPCInfo(manager_id: str, host: str, endpoint: EndpointDescriptor, online: bool, last_seen: datetime | None = None, devices: tuple[DeviceInfo, ...] = ())

One Lab PC (device manager) and the devices it registered with Central.

LeaseInfo dataclass

LeaseInfo(lease_id: str, device_id: str, user: str, created_at: datetime, expires_at: datetime, state: str, last_renewed_at: datetime | None = None, last_activity_at: datetime | None = None, idle_timeout_seconds: int | None = None)

status property

status: str

Compatibility alias for the pre-v1 field name.

Measurement dataclass

Measurement(operation_id: str, sequence: int, timestamp_ns: int, value: float, unit: str, quality: MeasurementQuality, status: str, channel: str | None = None)

One typed scalar measurement returned by a device RPC.

parse_datetime

parse_datetime(value: str | datetime) -> datetime

Parse an ISO-8601 timestamp and always return an aware UTC value.

Errors

exceptions

Stable client exceptions for Central HTTP and direct device RPC calls.

LabClientError

Bases: Exception

Base exception for client-library failures.

AuthenticationError

AuthenticationError(message: str, *, error_code: str | None = None)

Bases: _CentralResourceError

Raised when a Central API credential is missing or invalid.

PermissionDeniedError

PermissionDeniedError(message: str, *, error_code: str | None = None)

Bases: _CentralResourceError

Raised when the authenticated Central user lacks permission.

ResourceNotFoundError

ResourceNotFoundError(message: str, *, error_code: str | None = None)

Bases: _CentralResourceError

Raised when a requested Central resource does not exist.

ResourceConflictError

ResourceConflictError(message: str, *, error_code: str | None = None)

Bases: _CentralResourceError

Raised when a device is busy or another Central conflict occurs.

ServerConnectionError

Bases: LabClientError

Raised when Central or a Lab PC cannot be reached.

ServerResponseError

ServerResponseError(status_code: int, message: str, *, error_code: str | None = None)

Bases: LabClientError

Raised for an unexpected Central Server response.

NoAvailableDeviceError

Bases: LabClientError

Raised when no available device of the requested type exists.

LeaseAuthorityError

Bases: LabClientError

Raised after automatic renewal can no longer preserve lease authority.

DeviceRpcError

DeviceRpcError(status_code: StatusCode, message: str, *, error_code: str | None = None, operation_id: str | None = None, retryable: bool | None = None, operation_may_have_completed: bool | None = None)

Bases: LabClientError

Base for canonical gRPC failures with Labnet metadata preserved.

translate_grpc_error

translate_grpc_error(exc: RpcError) -> DeviceRpcError

Convert sync or aio gRPC errors into stable Labnet exceptions.