evdev: Linux Input Subsystem Bindings

1.9.3 · active · verified Sun Apr 12

evdev provides Python bindings to the generic input event interface in Linux, allowing user-space programs to read and write input events from devices like keyboards, mice, and touchscreens. It also includes bindings to uinput, enabling the creation and handling of virtual input devices to inject events directly into the kernel's input subsystem. As of February 2026, the current version is 1.9.3, and the library maintains an active development and release schedule.

Warnings

Install

Imports

Quickstart

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.")

view raw JSON →