Hook and simulate keyboard events on Windows and Linux
—
Global keyboard event monitoring and hooking system for capturing all keyboard activity system-wide. The keyboard package provides comprehensive event handling that works regardless of window focus, supporting both blocking and non-blocking event capture with filtering capabilities.
Install global listeners that capture all keyboard events from all keyboards connected to the system.
def hook(callback, suppress=False, on_remove=lambda: None):
"""
Installs a global listener on all available keyboards, invoking callback
each time a key is pressed or released.
Parameters:
- callback: Function to call with KeyboardEvent
- suppress: If True, suppresses the key from reaching other applications
- on_remove: Function called when hook is removed
Returns:
Function to remove the hook
"""
def unhook(remove):
"""
Removes a previously added hook, either by callback or by the return value
of hook().
Parameters:
- remove: Hook callback or remove function returned by hook()
"""
def unhook_all():
"""
Removes all keyboard hooks in use, including hotkeys, abbreviations, word
listeners, recorders and waits.
"""Filter events by press or release actions.
def on_press(callback, suppress=False):
"""
Invokes callback for every KEY_DOWN event.
Parameters:
- callback: Function to call with KeyboardEvent
- suppress: If True, suppresses the key from reaching other applications
Returns:
Function to remove the hook
"""
def on_release(callback, suppress=False):
"""
Invokes callback for every KEY_UP event.
Parameters:
- callback: Function to call with KeyboardEvent
- suppress: If True, suppresses the key from reaching other applications
Returns:
Function to remove the hook
"""Hook events for individual keys rather than all keyboard activity.
def hook_key(key, callback, suppress=False):
"""
Hooks key up and key down events for a single key. Returns the event handler
created. To remove a hooked key use unhook_key(key) or unhook_key(handler).
Parameters:
- key: Key name, scan code, or key object to hook
- callback: Function to call with KeyboardEvent
- suppress: If True, suppresses the key from reaching other applications
Returns:
Function to remove the hook
"""
def on_press_key(key, callback, suppress=False):
"""
Invokes callback for KEY_DOWN event related to the given key.
Parameters:
- key: Key name, scan code, or key object to hook
- callback: Function to call with KeyboardEvent
- suppress: If True, suppresses the key from reaching other applications
Returns:
Function to remove the hook
"""
def on_release_key(key, callback, suppress=False):
"""
Invokes callback for KEY_UP event related to the given key.
Parameters:
- key: Key name, scan code, or key object to hook
- callback: Function to call with KeyboardEvent
- suppress: If True, suppresses the key from reaching other applications
Returns:
Function to remove the hook
"""Prevent specific keys from reaching other applications.
def block_key(key):
"""
Suppresses all key events of the given key, regardless of modifiers.
Parameters:
- key: Key name, scan code, or key object to block
Returns:
Function to remove the block
"""
# Alias for removing key blocks
unblock_key = unhook_key # Remove key block (alias for unhook_key)import keyboard
def on_key_event(event):
print(f'Key {event.name} was {"pressed" if event.event_type == "down" else "released"}')
print(f'Scan code: {event.scan_code}, Time: {event.time}')
# Install global hook
remove_hook = keyboard.hook(on_key_event)
# Let it run for a while
keyboard.wait('esc')
# Clean up
remove_hook()import keyboard
def on_key_press(event):
print(f'Key pressed: {event.name}')
if event.name in ['ctrl', 'alt', 'shift']:
print('Modifier key detected!')
keyboard.on_press(on_key_press)
keyboard.wait('esc')import keyboard
def on_space_press(event):
print('Space bar pressed!')
def on_enter_press(event):
print('Enter key pressed!')
# Hook specific keys
keyboard.on_press_key('space', on_space_press)
keyboard.on_press_key('enter', on_enter_press)
keyboard.wait('esc')
keyboard.unhook_all()import keyboard
# Block the Windows key
remove_block = keyboard.block_key('windows')
print('Windows key is now blocked. Press ESC to exit.')
keyboard.wait('esc')
# Restore the Windows key
remove_block()import keyboard
def log_and_suppress(event):
print(f'Intercepted: {event.name}')
return False # Suppress the event
# Suppress all 'a' key presses
keyboard.hook_key('a', log_and_suppress, suppress=True)
print('All "a" key presses are now suppressed. Press ESC to exit.')
keyboard.wait('esc')
keyboard.unhook_all()class KeyboardEvent:
"""
Represents a keyboard event with complete timing and key information.
"""
event_type: str # 'down' for press, 'up' for release
scan_code: int # Physical key identifier (hardware-specific)
name: str # Human-readable key name (e.g., 'a', 'space', 'ctrl')
time: float # Event timestamp in seconds since epoch
device: int # Device identifier (None on Windows)
modifiers: list # List of active modifier keys
is_keypad: bool # True if key is from numeric keypad
def to_json(self, ensure_ascii=False) -> str:
"""Serialize event to JSON string."""KEY_DOWN: str = 'down' # Event type for key press
KEY_UP: str = 'up' # Event type for key releaseThe keyboard package normalizes key names for consistent cross-platform behavior:
def normalize_name(name: str) -> str:
"""
Given a key name (e.g. "LEFT CONTROL"), clean up the string and convert to
the canonical representation (e.g. "left ctrl") if one is known.
Parameters:
- name: Raw key name to normalize
Returns:
Normalized key name
"""Common key name mappings:
'return' → 'enter''control' → 'ctrl''left arrow' → 'left''spacebar' → 'space''escape' → 'esc'event.device == None)Event hooks can fail if:
The package will raise OSError for unsupported platforms and may silently fail to capture events in restricted environments.
Install with Tessl CLI
npx tessl i tessl/pypi-keyboard