Install & Compatibility
Where this runs
tested against v2.0.7 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.083s · 18.1MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 1.6s · import 0.076s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
CanStack
✓ from isotp import CanStack
✗ import isotp
This quickstart demonstrates setting up a virtual CAN bus and an ISO-TP `CanStack` to send and receive a multi-frame message. It includes robust error handling for CAN bus initialization and provides an example of a diagnostic service request and response.
import can
import isotp
import time
import os
# Configure CAN bus (uses 'virtual' bus by default for easy testing)
# For a real setup, replace 'virtual' with your bus type (e.g., 'socketcan', 'peak')
# and 'vcan0' with your channel. For Linux virtual CAN, ensure 'vcan0' is up:
# Example: sudo modprobe vcan; sudo ip link add dev vcan0 type vcan; sudo ip link set up vcan0
bus_type = os.environ.get('CAN_BUSTYPE', 'virtual')
can_channel = os.environ.get('CAN_CHANNEL', 'vcan0')
# Attempt to open the specified CAN bus. Fallback to a mock bus for script execution.
try:
bus = can.Bus(channel=can_channel, bustype=bus_type)
print(f"CAN bus opened successfully: {can_channel} ({bus_type})")
except Exception as e:
print(f"Could not open CAN bus '{can_channel}' with type '{bus_type}'. Error: {e}")
print("Falling back to a mock virtual bus for demonstration purposes.")
bus = can.interface.Bus(bustype='virtual', channel='vcan0', is_extended_id=False)
# Define ISO-TP addressing parameters for a physical communication
# rxid: The CAN ID this ISO-TP stack expects to receive (from ECU).
# txid: The CAN ID this ISO-TP stack will send (to ECU).
addr = isotp.Address(
isotp.TargetAddressType.N_PHYSICAL,
rxid=0x7E8,
txid=0x7E0
)
# Create an ISO-TP stack using the high-level CanStack interface
stack = isotp.stack.CanStack(bus=bus, address=addr)
# Send an ISO-TP message (e.g., a diagnostic service request)
payload_to_send = b'\x22\xF1\x90\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A'
print(f"Sending ISO-TP message ({len(payload_to_send)} bytes): {payload_to_send.hex()}")
stack.send(payload_to_send, timeout=0.5) # Add a timeout for sending
# Wait a short moment for bus activity / reply
time.sleep(0.1)
# Attempt to receive an ISO-TP message (e.g., an ECU response)
print("Attempting to receive ISO-TP message (timeout=1.0s)...")
received_data = stack.recv(timeout=1.0) # Blocking receive with a timeout
if received_data is not None:
print(f"Received ISO-TP message ({len(received_data)} bytes): {received_data.hex()}")
else:
print("No ISO-TP message received within the timeout.")
# Clean up the CAN bus
bus.shutdown()
print("CAN bus shut down.")
Upgrade
Version history
2.0.7latest on PyPI · released May 14, 2025
Audit
Dependencies
python-canrequiredProvides the underlying CAN bus interface for `can-isotp`.