hidapi Python Wrapper
hidapi is a Python library providing a Cython interface to the native HIDAPI library, enabling cross-platform communication with USB Human Interface Devices (HID). It works on Linux, Windows, and macOS. The current version is 0.15.0, with regular updates typically following the underlying HIDAPI C library.
Warnings
- gotcha The `hidapi` Python package requires the underlying native `hidapi` library to be installed on your system. `pip install hidapi` only installs the Python bindings, not the C library itself. Users often encounter `IOError` or `OSError` if the native library is missing or improperly configured.
- gotcha On Linux, accessing HID devices typically requires special permissions. Without them, `hid.open()` calls will fail with `IOError`.
- gotcha When reading or writing HID reports, the first byte often represents the 'Report ID'. If your device uses numbered reports, this byte will be the Report ID. If not, it's typically `0x00`. Misinterpreting this can lead to incorrect data parsing or writing issues.
Install
-
pip install hidapi -
sudo apt-get install python3-dev libusb-1.0-0-dev libudev-dev && pip install hidapi -
brew install hidapi && pip install hidapi
Imports
- hid
import hid
- device
h = hid.device()
Quickstart
import hid
import os
import time
# --- Enumerate devices (useful for finding VID/PID) ---
print('Enumerating HID devices:')
for device_dict in hid.enumerate():
print('---')
for key, value in device_dict.items():
print(f'{key}: {value}')
print('---\n')
# --- Connect, read, and write (example with placeholder VID/PID) ---
# Replace with your device's Vendor ID and Product ID.
# On Linux, you may need appropriate udev rules or root privileges.
# On Windows, you might need hidapi.dll in your PATH.
VENDOR_ID = int(os.environ.get('HIDAPI_VENDOR_ID', '0x0000'), 16) # Example: 0x534C for Trezor
PRODUCT_ID = int(os.environ.get('HIDAPI_PRODUCT_ID', '0x0000'), 16) # Example: 0x0001 for Trezor One
if VENDOR_ID == 0x0000 or PRODUCT_ID == 0x0000:
print('Warning: Please set HIDAPI_VENDOR_ID and HIDAPI_PRODUCT_ID environment variables for a real test.')
print('Falling back to placeholder values; device opening may fail.')
try:
print(f'Attempting to open device VID: {hex(VENDOR_ID)}, PID: {hex(PRODUCT_ID)}')
h = hid.device()
h.open(VENDOR_ID, PRODUCT_ID)
print(f'Manufacturer: {h.get_manufacturer_string()}')
print(f'Product: {h.get_product_string()}')
print(f'Serial No: {h.get_serial_number_string()}')
h.set_nonblocking(1) # Enable non-blocking mode
# Example: Write some data (replace with actual device commands)
print('Writing example data...')
# Ensure data length matches device report size, padded with zeros if needed.
# The first byte might be a Report ID, or 0 if not used by the device.
data_to_write = [0, 63, 35, 35] + [0] * 60 # Example 64-byte report
h.write(data_to_write)
time.sleep(0.05)
# Example: Read data
print('Reading data...')
read_data = []
while True:
d = h.read(64) # Read up to 64 bytes
if d:
read_data.extend(d)
else:
break
if read_data:
print(f'Read data: {read_data}')
else:
print('No data read.')
print('Closing the device.')
h.close()
except IOError as ex:
print(f'Error opening or communicating with device: {ex}')
print('Ensure the device is connected and permissions are correct.')
except Exception as e:
print(f'An unexpected error occurred: {e}')