Install & Compatibility
Where this runs
tested against v1.26.0 · 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.114s · 18.9MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 1.6s · import 0.117s · 19MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Client
✓ from udsoncan.client import Client
Server
✓ from udsoncan.server import Server
IsoTPSocketConnection
✓ from udsoncan.connections import IsoTPSocketConnection
LoopbackConnection
✓ from udsoncan.connections import LoopbackConnection
services
✓ import udsoncan.services as services
Dtc
✓ from udsoncan import Dtc
NegativeResponseException
✓ from udsoncan.exceptions import NegativeResponseException
TimeoutException
✓ from udsoncan.exceptions import TimeoutException
This quickstart demonstrates setting up a UDS client and server using `udsoncan` with a `LoopbackConnection`. This allows for in-process communication without needing external hardware or `python-can`. The server implements basic handlers for `ReadDataByIdentifier` and `DiagnosticSessionControl`. The client then interacts with this server to read a VIN, change a session, and handle an unsupported DID request.
import udsoncan
from udsoncan.client import Client
from udsoncan.server import Server
from udsoncan.connections import LoopbackConnection
from udsoncan.services import ReadDataByIdentifier, DiagnosticSessionControl
from udsoncan.exceptions import NegativeResponseException
# Define a simple UDS server application logic
class MyServerApplication:
def __init__(self):
self.data_store = {
0xF190: b'PythonUDS', # Example VIN
0xF180: b'v1.0' # Example Software version
}
self.current_session = 1 # Default session
def read_data_by_identifier(self, did, access_level=None):
if did in self.data_store:
return self.data_store[did]
raise NegativeResponseException(0x10) # SubFunction Not Supported if DID is unknown
def diagnostic_session_control(self, session_id, access_level=None):
if session_id in [1, 2, 3]: # Default, Programming, Extended
self.current_session = session_id
return b''
raise NegativeResponseException(0x10) # SubFunction Not Supported if session is unknown
def get_did_config(self):
# Define how DIDs are encoded/decoded for the server
return {
0xF190: {'data_size': 9, 'codec': udsoncan.AsciiCodec},
0xF180: {'data_size': 4, 'codec': udsoncan.AsciiCodec},
}
# Configure client and server to use an in-memory loopback connection
conn = LoopbackConnection(name='test_bus')
# Server setup
server_app = MyServerApplication()
server_config = udsoncan.ServerConfiguration()
server_config.default_response_pending_timeout = 200 # ms
server_config.set_did_config(server_app.get_did_config())
# Link server services to the application methods
server_config.request_handler = {
ReadDataByIdentifier: server_app.read_data_by_identifier,
DiagnosticSessionControl: server_app.diagnostic_session_control
}
server = Server(conn, server_config)
server.start()
# Client setup
client = Client(conn, request_timeout=2) # 2 seconds timeout
try:
client.open()
# Example 1: Read VIN (DID F190)
response = client.read_data_by_identifier([0xF190])
vin = response.values[0xF190]
print(f"VIN: {vin.decode('ascii')}")
# Example 2: Change diagnostic session to Extended Diagnostic Session (ID 0x03)
response = client.diagnostic_session_control(3)
print(f"Session changed to: {response.service_data.session_id} (Success)")
# Example 3: Try reading an unsupported DID (will raise NegativeResponseException)
try:
client.read_data_by_identifier([0x1234])
except NegativeResponseException as e:
print(f"Tried reading unsupported DID 0x1234: Received NRC {hex(e.response.code)}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
client.close()
server.stop()
print("Client and server stopped.")
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'can'
You are attempting to use a CAN-based connection (e.g., `IsoTPSocketConnection`) but the `python-can` library is not installed.
fixInstall the `python-can` library: `pip install python-can` (or `pip install udsoncan[can]` to install `udsoncan` with its `can` extras).
udsoncan.exceptions.TimeoutException: No response received from the server (request=...) (timeout=...s)
The UDS server did not respond within the client's configured request timeout (P2 or P2* timeout). This can be due to an inactive server, incorrect CAN IDs, a physical connection issue, or an overloaded/slow server.
fixVerify the UDS server is active and accessible. Double-check CAN IDs, physical wiring, and baud rates. If the server is genuinely slow, increase `client.request_timeout` or the P2/P2* timeout settings in the client configuration.
AttributeError: module 'udsoncan.services' has no attribute 'MyCustomService'
You are trying to import or reference a UDS service class that does not exist in the `udsoncan.services` module or is misspelled. Services like `ReadDataByIdentifier`, `DiagnosticSessionControl` are defined there.
fixCheck the `udsoncan.services` module for the correct class name for the UDS service you intend to use. Ensure your import statement and class reference match the library's API (e.g., `from udsoncan.services import ReadDataByIdentifier`).
udsoncan.exceptions.NegativeResponseException: Server responded with negative response code 0x78 (Response Pending)
The UDS server sent a 'Response Pending' NRC (0x78) but then failed to send a final positive response or another NRC within the P2* timeout. This often indicates a server processing delay exceeding the client's tolerance, or a server internal issue.
fixIncrease the `P2_star_timeout` in the client's configuration if the server is known to take a long time to process. Investigate the server-side behavior if it consistently fails to respond after 0x78. For `udsoncan` v1.24.0+, you can use `nrc_78_received_callback` for specific handling.
Upgrade
Version history
1.26.0latest on PyPI · released Jun 9, 2026
Audit
Dependencies
python-canoptionalRequired for CAN bus communication via IsoTPSocketConnection or other CAN-based connections. Not strictly required for the core library if using other connection types (e.g., LoopbackConnection, DoIPConnection).