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 interfaceagent/iface(or the numeric id fromcan-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 aquic://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.
Release files for python-can-hub 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| python_can_hub-0.3.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl | Python 3 | none | Linux glibc 2.28+ ARMv7l, Linux glibc 2.31+ ARMv7l | Details |
| python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl | Python 3 | none | Linux glibc 2.26+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.28+ ARM64, Linux glibc 2.26+ ARM64 | Details |
Total release size: 11.5 MB
Release files / python_can_hub-0.3.0-py3-none-win_amd64.whl
| Download URL | python_can_hub-0.3.0-py3-none-win_amd64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
f96fc280382e12a7499dd4586b47559ffd7ba18cd484b0ea938c7b0e6d1feb2c
|
|
BLAKE2b-256 checksum How to use checksums |
74e28cd96d0bfdc3d2516ef3c2b08dc55f1a56b4adce5f49668e507672817bbc
|
| 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 4, 2026.
Transparency logRelease files / python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl
| Download URL | python_can_hub-0.3.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Linux glibc 2.28+ ARMv7l Linux glibc 2.31+ ARMv7l Python 3 |
|
SHA-256 checksum How to use checksums |
86efcf58fb74e2aa92e38f9679b037ae9519d01e3c7b1f4c318d82aaa139a413
|
|
BLAKE2b-256 checksum How to use checksums |
b81513334792669baa95eaed4c21359c1f26da1665a3962621061d99fc60c58d
|
| 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 4, 2026.
Transparency logRelease files / python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl
| Download URL | python_can_hub-0.3.0-py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | Linux glibc 2.26+ x86-64 Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
d3ac2f9d9b0b80e441332cd6b37677a69553f090c8e09ec11b7e2e596e05adf6
|
|
BLAKE2b-256 checksum How to use checksums |
2005c6f5be3afd2d761ae56132cdd72f4bef8898606261c15528d631872c243a
|
| 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 4, 2026.
Transparency logRelease files / python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
| Download URL | python_can_hub-0.3.0-py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 3.4 MB |
| Tags | Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
c1404633d6f566c01c79a3aa86a2238292a68b26071bb0ee657572310f82ea1f
|
|
BLAKE2b-256 checksum How to use checksums |
35b8aac19434dc5ba8093e72134514c2719d9b20ae6fb3d19723c372eb1a1e01
|
| 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 4, 2026.
Transparency log