Skip to main content

python-can-hub

Native python-can backend for can-hub: consume remote CAN interfaces exported by can-hub agents, directly over the binary protocol — unix socket, plain TCP, TLS or QUIC, with mTLS identity and TOFU pinning on the encrypted transports. No bridge process in between.

import can

bus = can.Bus(
    interface="canhub",
    channel="truck42/can0",
    url="quic://hub.example.com:7227",
)
bus.send(can.Message(arbitration_id=0x123, data=b"\xDE\xAD\xBE\xEF"))
for message in bus:
    print(message)
  • channel: namespaced interface agent/iface (or the numeric id from can-hub-client list).
  • url: omit to connect to the local hub unix socket.
  • state_dir: client TLS identity + pin store location (tls/quic).
  • receive_own_messages: standard python-can echo semantics.
  • reliable: carry the channel on a dedicated reliable QUIC stream (lossless, ordered) instead of the lossy datagram plane. Needs a quic:// url and a hub that advertises the capability; otherwise the open fails.

Write access follows the hub client ACLs: if the ACL grants read-only, the bus opens read-only and send() raises.

Drop counters

Two drops happen inside the library and never reach the hub, so the hub's own counters cannot show them: send() raises when the pace relayed by the hub leaves no budget for the frame, and the receive ring overwrites its oldest entry when you read slower than the bus produces. drop_counters() returns both as monotonic totals, so a quiet bus is distinguishable from a lossy one:

bus.drop_counters()     # {"rate_limited": 0, "ring_dropped": 12}

Listing interfaces

CanHubBus.list_interfaces() asks a hub for the interfaces it exports. Each entry is a python-can config dict you can splat straight into can.Bus:

from canhub import CanHubBus
import can

for config in CanHubBus.list_interfaces(url="quic://hub.example.com:7227"):
    print(config["channel"])          # e.g. "can-agent/can0"
bus = can.Bus(**CanHubBus.list_interfaces()[0])   # first interface, local hub

It accepts the same connection arguments as the bus (url, identity_cert, identity_key, hub_fingerprint, state_dir); omit url to query the local hub unix socket.

This also wires python-can's discovery: can.detect_available_configs("canhub") returns the same dicts. With no explicit target it reads the connection from the environment — CANHUB_URL, CANHUB_STATE_DIR, CANHUB_IDENTITY_CERT, CANHUB_IDENTITY_KEY, CANHUB_HUB_FINGERPRINT — falling back to the local hub unix socket. So CANHUB_URL=quic://hub.example.com:7227 points discovery at a remote host without any code.

The wheel bundles libcanhub.so with the TLS/QUIC stack linked in statically; the only runtime dependency is glibc.

Testing

The unit tests stub the native library, so they run without a build:

pip install -e python/.[test]
pytest python/tests

The backend is also exercised end-to-end against real binaries (recv, send, list_interfaces, and can.detect_available_configs discovery) by test/e2e/tests/python_can.robot; run the whole bench with make e2e.

Building from source

./scripts/build-python-wheel.sh        # host arch, glibc-tagged (local dev)
pip install python/dist/*.whl

Distributable manylinux wheels are built per architecture in a manylinux container and repaired by auditwheel (needs docker, plus QEMU binfmt for the cross arches):

./scripts/build-python-wheel.sh x86_64   # python/dist/x86_64/*.whl
./scripts/build-python-wheel.sh aarch64
./scripts/build-python-wheel.sh armv7l

The release workflow builds these three on native runners (aarch64/armv7l on the arm64 hosted runner, no QEMU) plus a cross-compiled win_amd64 wheel, and publishes all four to PyPI on a v* tag.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

python_can_hub-0.3.0-py3-none-win_amd64.whl (2.5 MB view details)

Uploaded Python 3Windows x86-64

python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl (2.6 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARMv7lmanylinux: glibc 2.31+ ARMv7l

python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl (3.1 MB view details)

Uploaded Python 3manylinux: glibc 2.26+ x86-64manylinux: glibc 2.28+ x86-64

python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (3.4 MB view details)

Uploaded Python 3manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

File details

Details for the file python_can_hub-0.3.0-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for python_can_hub-0.3.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 f96fc280382e12a7499dd4586b47559ffd7ba18cd484b0ea938c7b0e6d1feb2c
MD5 db8beecc3678673f814462f430089829
BLAKE2b-256 74e28cd96d0bfdc3d2516ef3c2b08dc55f1a56b4adce5f49668e507672817bbc

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_can_hub-0.3.0-py3-none-win_amd64.whl:

Publisher: release.yml on can-hub-io/can-hub

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

File details

Details for the file python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl.

File metadata

File hashes

Hashes for python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl
Algorithm Hash digest
SHA256 86efcf58fb74e2aa92e38f9679b037ae9519d01e3c7b1f4c318d82aaa139a413
MD5 dd432f6ea0050ce7c25201d8f09df082
BLAKE2b-256 b81513334792669baa95eaed4c21359c1f26da1665a3962621061d99fc60c58d

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl:

Publisher: release.yml on can-hub-io/can-hub

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

File details

Details for the file python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d3ac2f9d9b0b80e441332cd6b37677a69553f090c8e09ec11b7e2e596e05adf6
MD5 0319e3ed6b46698e1a278dc7650c12f3
BLAKE2b-256 2005c6f5be3afd2d761ae56132cdd72f4bef8898606261c15528d631872c243a

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on can-hub-io/can-hub

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

File details

Details for the file python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c1404633d6f566c01c79a3aa86a2238292a68b26071bb0ee657572310f82ea1f
MD5 012285a217a38c368670ccee6162a109
BLAKE2b-256 35b8aac19434dc5ba8093e72134514c2719d9b20ae6fb3d19723c372eb1a1e01

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on can-hub-io/can-hub

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