Install & Compatibility
Where this runs
tested against v? · pip install
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.95 runs
build_error
glibcpy 3.10–3.95 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
InputDevice
✓ from evdev import InputDevice
categorize
✓ from evdev import categorize
ecodes
✓ from evdev import ecodes
list_devices
✓ from evdev import list_devices
UInput
✓ from evdev import UInput
This quickstart demonstrates how to list available Linux input devices and then continuously read events from a selected device, typically a keyboard. It prints key press events and basic mouse movements. Remember that `evdev` requires direct access to `/dev/input/` devices, which often means running with sufficient user permissions (e.g., being in the `input` group).
import evdev
from evdev import InputDevice, categorize, ecodes
import os
# Listing accessible event devices
print('Listing available input devices:')
devices = [InputDevice(path) for path in evdev.list_devices()]
if not devices:
print("No input devices found. Ensure your user has read/write access to /dev/input/ and devices are connected.")
for device in devices:
print(f"{device.path}: {device.name} ({device.phys})")
# Example: Reading events from the first available keyboard-like device
# (You might need to adjust the path or device selection for your system)
keyboard_device = None
for device in devices:
# Heuristic: look for devices with EV_KEY (keyboard events)
if ecodes.EV_KEY in device.capabilities():
keyboard_device = device
break
if keyboard_device:
print(f"\nReading events from: {keyboard_device.path} - {keyboard_device.name}")
print("Press Ctrl+C to stop.")
try:
for event in keyboard_device.read_loop():
if event.type == ecodes.EV_KEY:
key_event = categorize(event)
if key_event.keystate == key_event.key_down:
print(f"Key pressed: {key_event.keycode} (Scancode: {key_event.scancode})")
elif event.type == ecodes.EV_REL:
# Example for mouse movement
if event.code == ecodes.REL_X:
print(f"Mouse X movement: {event.value}")
elif event.code == ecodes.REL_Y:
print(f"Mouse Y movement: {event.value}")
# Add more event types (EV_ABS, EV_SYN, etc.) as needed
except PermissionError:
print(f"\nPermission denied for {keyboard_device.path}. Ensure your user is in the 'input' group.")
except OSError as e:
print(f"\nError reading device: {e}. Device might have been unplugged or is inaccessible.")
except KeyboardInterrupt:
print("\nStopped reading events.")
else:
print("\nNo suitable keyboard-like input device found to demonstrate event reading.")
Debug
Known issues
gotchaInstalling `evdev` requires Linux development headers and a C compiler (like `gcc`) to be installed on your system. Without these, `pip install evdev` will fail during compilation.fixOn Debian/Ubuntu: `sudo apt install python3-dev python3-pip gcc linux-headers-$(uname -r)`. On RedHat/Fedora: `sudo dnf install python3-devel python3-pip gcc kernel-headers-$(uname -r)`.
affects: All versions
gotchaUser permissions: To read or write events, your user account must have appropriate permissions to access `/dev/input/eventX` devices. This usually means being a member of the 'input' user group.fixAdd your user to the 'input' group: `sudo usermod -aG input $USER`. You will need to log out and log back in for the changes to take effect.
affects: All versions
gotchaWhen installing in a virtual environment, if you encounter `error: externally-managed-environment`, `pip` is attempting to install system-wide. This often means the virtual environment is not correctly activated or configured.fixEnsure your virtual environment is activated (`source /path/to/venv/bin/activate`) before running `pip install evdev`. If activating from within an IDE or tool, verify it's using the venv's Python. Alternatively, use `python3 -m pip install evdev` after activation.
affects: Python 3.11+ (due to PEP 668)
gotchaWhen injecting events with `UInput`, certain complex characters (e.g., ':') may not be easily translated and require explicit kernel keyboard translation table knowledge, which is beyond `evdev`'s scope.fixFor complex or localized character injection, consider higher-level input simulation tools or libraries that abstract kernel-specific mappings, or directly manage kernel keycode/scancode translations if possible.
affects: All versions
gotchaThe `upload_effect()` method for Force Feedback (FF) effects might not write the kernel-assigned ID back to the `Effect` object, leading to silent failures or incorrect behavior if you try to re-upload or manage the effect later based on its ID.fixRefer to GitHub issues for potential workarounds or ensure you manage effect IDs independently if re-uploading or modifying effects after initial upload. This is a known open issue (#250 on GitHub).
affects: All versions up to 1.9.3
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'evdev'
The 'evdev' library is not installed in the Python environment being used.
fixInstall the evdev package using pip: `pip install evdev` or `python3 -m pip install evdev`. If using a binary package, `python3 -m pip install evdev-binary`.
PermissionError: [Errno 13] Permission denied: '/dev/input/eventX'
The current user does not have the necessary read/write permissions to access the input device files in `/dev/input/`.
fixAdd your user to the 'input' group: `sudo usermod -a -G input $USER` and then log out and back in. Alternatively, run the script with `sudo`, though this is generally less recommended for security reasons.
AttributeError: 'InputDevice' object has no attribute 'fn'
The 'fn' attribute of the InputDevice object has been deprecated in newer versions of the evdev library in favor of 'path'.
fixReplace `.fn` with `.path` when accessing the device file path, or downgrade the evdev library to an older version (e.g., `pip install evdev==1.8`) if the dependent code cannot be easily updated.
ImportError: cannot import name 'InputDevice' from partially initialized module 'evdev'
This often indicates a circular import, most commonly when a Python file named `evdev.py` exists in the same directory as the script attempting to import the `evdev` library, leading to a conflict.
fixRename your local Python file that has the same name as the library (e.g., from `evdev.py` to `my_evdev_script.py`) to avoid module name conflicts.
Upgrade
Version history
2.0.0latest on PyPI · released Aug 23, 2026
Audit
Dependencies
No dependency data recorded yet.