{"id":4530,"library":"evdev","title":"evdev: Linux Input Subsystem Bindings","description":"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.","status":"active","version":"1.9.3","language":"en","source_language":"en","source_url":"https://github.com/gvalkov/python-evdev","tags":["linux","input","evdev","uinput","hardware","device","kernel","low-level"],"install":[{"cmd":"pip install evdev","lang":"bash","label":"Install from PyPI (requires OS dependencies)"}],"dependencies":[],"imports":[{"symbol":"InputDevice","correct":"from evdev import InputDevice"},{"symbol":"categorize","correct":"from evdev import categorize"},{"symbol":"ecodes","correct":"from evdev import ecodes"},{"symbol":"list_devices","correct":"from evdev import list_devices"},{"symbol":"UInput","correct":"from evdev import UInput"}],"quickstart":{"code":"import evdev\nfrom evdev import InputDevice, categorize, ecodes\nimport os\n\n# Listing accessible event devices\nprint('Listing available input devices:')\ndevices = [InputDevice(path) for path in evdev.list_devices()]\nif not devices:\n    print(\"No input devices found. Ensure your user has read/write access to /dev/input/ and devices are connected.\")\nfor device in devices:\n    print(f\"{device.path}: {device.name} ({device.phys})\")\n\n# Example: Reading events from the first available keyboard-like device\n# (You might need to adjust the path or device selection for your system)\nkeyboard_device = None\nfor device in devices:\n    # Heuristic: look for devices with EV_KEY (keyboard events)\n    if ecodes.EV_KEY in device.capabilities():\n        keyboard_device = device\n        break\n\nif keyboard_device:\n    print(f\"\\nReading events from: {keyboard_device.path} - {keyboard_device.name}\")\n    print(\"Press Ctrl+C to stop.\")\n    try:\n        for event in keyboard_device.read_loop():\n            if event.type == ecodes.EV_KEY:\n                key_event = categorize(event)\n                if key_event.keystate == key_event.key_down:\n                    print(f\"Key pressed: {key_event.keycode} (Scancode: {key_event.scancode})\")\n            elif event.type == ecodes.EV_REL:\n                # Example for mouse movement\n                if event.code == ecodes.REL_X:\n                    print(f\"Mouse X movement: {event.value}\")\n                elif event.code == ecodes.REL_Y:\n                    print(f\"Mouse Y movement: {event.value}\")\n            # Add more event types (EV_ABS, EV_SYN, etc.) as needed\n    except PermissionError:\n        print(f\"\\nPermission denied for {keyboard_device.path}. Ensure your user is in the 'input' group.\")\n    except OSError as e:\n        print(f\"\\nError reading device: {e}. Device might have been unplugged or is inaccessible.\")\n    except KeyboardInterrupt:\n        print(\"\\nStopped reading events.\")\nelse:\n    print(\"\\nNo suitable keyboard-like input device found to demonstrate event reading.\")","lang":"python","description":"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)."},"warnings":[{"fix":"On 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)`.","message":"Installing `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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Add 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.","message":"User 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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure 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.","message":"When 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.","severity":"gotcha","affected_versions":"Python 3.11+ (due to PEP 668)"},{"fix":"For 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.","message":"When 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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Refer 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).","message":"The `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.","severity":"gotcha","affected_versions":"All versions up to 1.9.3"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}