• Stars
    star
    3,683
  • Rank 11,427 (Top 0.3 %)
  • Language
    Python
  • License
    MIT License
  • Created almost 11 years ago
  • Updated 20 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Hook and simulate global keyboard events on Windows and Linux.

This project is currently unmaintained. It works for many cases, and I wish to pick it up again in the future, but you might encounter some friction and limited features using it.



keyboard

Take full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more.

Features

  • Global event hook on all keyboards (captures keys regardless of focus).
  • Listen and send keyboard events.
  • Works with Windows and Linux (requires sudo), with experimental OS X support (thanks @glitchassassin!).
  • Pure Python, no C modules to be compiled.
  • Zero dependencies. Trivial to install and deploy, just copy the files.
  • Python 2 and 3.
  • Complex hotkey support (e.g. ctrl+shift+m, ctrl+space) with controllable timeout.
  • Includes high level API (e.g. record and play, add_abbreviation).
  • Maps keys as they actually are in your layout, with full internationalization support (e.g. Ctrl+รง).
  • Events automatically captured in separate thread, doesn't block main program.
  • Tested and documented.
  • Doesn't break accented dead keys (I'm looking at you, pyHook).
  • Mouse support available via project mouse (pip install mouse).

Usage

Install the PyPI package:

pip install keyboard

or clone the repository (no installation required, source files are sufficient):

git clone https://github.com/boppreh/keyboard

or download and extract the zip into your project folder.

Then check the API docs below to see what features are available.

Example

Use as library:

import keyboard

keyboard.press_and_release('shift+s, space')

keyboard.write('The quick brown fox jumps over the lazy dog.')

keyboard.add_hotkey('ctrl+shift+a', print, args=('triggered', 'hotkey'))

# Press PAGE UP then PAGE DOWN to type "foobar".
keyboard.add_hotkey('page up, page down', lambda: keyboard.write('foobar'))

# Blocks until you press esc.
keyboard.wait('esc')

# Record events until 'esc' is pressed.
recorded = keyboard.record(until='esc')
# Then replay back at three times the speed.
keyboard.play(recorded, speed_factor=3)

# Type @@ then press space to replace with abbreviation.
keyboard.add_abbreviation('@@', '[email protected]')

# Block forever, like `while True`.
keyboard.wait()

Use as standalone module:

# Save JSON events to a file until interrupted:
python -m keyboard > events.txt

cat events.txt
# {"event_type": "down", "scan_code": 25, "name": "p", "time": 1622447562.2994788, "is_keypad": false}
# {"event_type": "up", "scan_code": 25, "name": "p", "time": 1622447562.431007, "is_keypad": false}
# ...

# Replay events
python -m keyboard < events.txt

Known limitations:

  • Events generated under Windows don't report device id (event.device == None). #21
  • Media keys on Linux may appear nameless (scan-code only) or not at all. #20
  • Key suppression/blocking only available on Windows. #22
  • To avoid depending on X, the Linux parts reads raw device files (/dev/input/input*) but this requires root.
  • Other applications, such as some games, may register hooks that swallow all key events. In this case keyboard will be unable to report events.
  • This program makes no attempt to hide itself, so don't use it for keyloggers or online gaming bots. Be responsible.
  • SSH connections forward only the text typed, not keyboard events. Therefore if you connect to a server or Raspberry PI that is running keyboard via SSH, the server will not detect your key events.

Common patterns and mistakes

Preventing the program from closing

import keyboard
keyboard.add_hotkey('space', lambda: print('space was pressed!'))
# If the program finishes, the hotkey is not in effect anymore.

# Don't do this! This will use 100% of your CPU.
#while True: pass

# Use this instead
keyboard.wait()

# or this
import time
while True:
    time.sleep(1000000)

Waiting for a key press one time

import keyboard

# Don't do this! This will use 100% of your CPU until you press the key.
#
#while not keyboard.is_pressed('space'):
#    continue
#print('space was pressed, continuing...')

# Do this instead
keyboard.wait('space')
print('space was pressed, continuing...')

Repeatedly waiting for a key press

import keyboard

# Don't do this!
#
#while True:
#    if keyboard.is_pressed('space'):
#        print('space was pressed!')
#
# This will use 100% of your CPU and print the message many times.

# Do this instead
while True:
    keyboard.wait('space')
    print('space was pressed! Waiting on it again...')

# or this
keyboard.add_hotkey('space', lambda: print('space was pressed!'))
keyboard.wait()

Invoking code when an event happens

import keyboard

# Don't do this! This will call `print('space')` immediately then fail when the key is actually pressed.
#keyboard.add_hotkey('space', print('space was pressed'))

# Do this instead
keyboard.add_hotkey('space', lambda: print('space was pressed'))

# or this
def on_space():
    print('space was pressed')
keyboard.add_hotkey('space', on_space)

# or this
while True:
    # Wait for the next event.
    event = keyboard.read_event()
    if event.event_type == keyboard.KEY_DOWN and event.name == 'space':
        print('space was pressed')

'Press any key to continue'

# Don't do this! The `keyboard` module is meant for global events, even when your program is not in focus.
#import keyboard
#print('Press any key to continue...')
#keyboard.get_event()

# Do this instead
input('Press enter to continue...')

# Or one of the suggestions from here
# https://stackoverflow.com/questions/983354/how-to-make-a-script-wait-for-a-pressed-key

API

Table of Contents

= 'down'
= 'up'

[source]

= {'alt', 'alt gr', 'ctrl', 'left alt', 'left ctrl', 'left shift', 'left windows', 'right alt', 'right ctrl', 'right shift', 'right windows', 'shift', 'windows'}
= {'alt', 'ctrl', 'shift', 'windows'}
= '0.13.5'

[source]

Returns True if key is a scan code or name of a modifier key.

[source]

Returns a list of scan codes associated with this key (name or scan code).

[source]

Parses a user-provided hotkey into nested tuples representing the parsed structure, with the bottom values being lists of scan codes. Also accepts raw scan codes, which are then wrapped in the required number of nestings.

Example:

parse_hotkey("alt+shift+a, alt+b, c")
#    Keys:    ^~^ ^~~~^ ^  ^~^ ^  ^
#    Steps:   ^~~~~~~~~~^  ^~~~^  ^

# ((alt_codes, shift_codes, a_codes), (alt_codes, b_codes), (c_codes,))

[source]

Sends OS events that perform the given hotkey hotkey.

  • hotkey can be either a scan code (e.g. 57 for space), single key (e.g. 'space') or multi-key, multi-step hotkey (e.g. 'alt+F4, enter').
  • do_press if true then press events are sent. Defaults to True.
  • do_release if true then release events are sent. Defaults to True.
send(57)
send('ctrl+alt+del')
send('alt+F4, enter')
send('shift+s')

Note: keys are released in the opposite order they were pressed.

[source]

Presses and holds down a hotkey (see send).

[source]

Releases a hotkey (see send).

[source]

Returns True if the key is pressed.

is_pressed(57) #-> True
is_pressed('space') #-> True
is_pressed('ctrl+space') #-> True

[source]

Calls the provided function in a new thread after waiting some time. Useful for giving the system some time to process an event, without blocking the current execution flow.

[source]

Installs a global listener on all available keyboards, invoking callback each time a key is pressed or released.

The event passed to the callback is of type keyboard.KeyboardEvent, with the following attributes:

  • name: an Unicode representation of the character (e.g. "&") or description (e.g. "space"). The name is always lower-case.
  • scan_code: number representing the physical key, e.g. 55.
  • time: timestamp of the time the event occurred, with as much precision as given by the OS.

Returns the given callback for easier development.

[source]

Invokes callback for every KEY_DOWN event. For details see hook.

[source]

Invokes callback for every KEY_UP event. For details see hook.

[source]

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

Note: this function shares state with hotkeys, so clear_all_hotkeys affects it as well.

[source]

Invokes callback for KEY_DOWN event related to the given key. For details see hook.

[source]

Invokes callback for KEY_UP event related to the given key. For details see hook.

[source]

Removes a previously added hook, either by callback or by the return value of hook.

[source]

Removes all keyboard hooks in use, including hotkeys, abbreviations, word listeners, recorders and waits.

[source]

Suppresses all key events of the given key, regardless of modifiers.

[source]

Whenever the key src is pressed or released, regardless of modifiers, press or release the hotkey dst instead.

[source]

Parses a user-provided hotkey. Differently from parse_hotkey, instead of each step being a list of the different scan codes for each key, each step is a list of all possible combinations of those scan codes.

[source]

Invokes a callback every time a hotkey is pressed. The hotkey must be in the format ctrl+shift+a, s. This would trigger when the user holds ctrl, shift and "a" at once, releases, and then presses "s". To represent literal commas, pluses, and spaces, use their names ('comma', 'plus', 'space').

  • args is an optional list of arguments to passed to the callback during each invocation.
  • suppress defines if successful triggers should block the keys from being sent to other programs.
  • timeout is the amount of seconds allowed to pass between key presses.
  • trigger_on_release if true, the callback is invoked on key release instead of key press.

The event handler function is returned. To remove a hotkey call remove_hotkey(hotkey) or remove_hotkey(handler). before the hotkey state is reset.

Note: hotkeys are activated when the last key is pressed, not released. Note: the callback is executed in a separate thread, asynchronously. For an example of how to use a callback synchronously, see wait.

Examples:

# Different but equivalent ways to listen for a spacebar key press.
add_hotkey(' ', print, args=['space was pressed'])
add_hotkey('space', print, args=['space was pressed'])
add_hotkey('Space', print, args=['space was pressed'])
# Here 57 represents the keyboard code for spacebar; so you will be
# pressing 'spacebar', not '57' to activate the print function.
add_hotkey(57, print, args=['space was pressed'])

add_hotkey('ctrl+q', quit)
add_hotkey('ctrl+alt+enter, space', some_callback)

[source]

Removes a previously hooked hotkey. Must be called with the value returned by add_hotkey.

[source]

Removes all keyboard hotkeys in use, including abbreviations, word listeners, recorders and waits.

[source]

Whenever the hotkey src is pressed, suppress it and send dst instead.

Example:

remap('alt+w', 'ctrl+up')

[source]

Builds a list of all currently pressed scan codes, releases them and returns the list. Pairs well with restore_state and restore_modifiers.

[source]

Given a list of scan_codes ensures these keys, and only these keys, are pressed. Pairs well with stash_state, alternative to restore_modifiers.

[source]

Like restore_state, but only restores modifier keys.

[source]

Sends artificial keyboard events to the OS, simulating the typing of a given text. Characters not available on the keyboard are typed as explicit unicode characters using OS-specific functionality, such as alt+codepoint.

To ensure text integrity, all currently pressed keys are released before the text is typed, and modifiers are restored afterwards.

  • delay is the number of seconds to wait between keypresses, defaults to no delay.
  • restore_state_after can be used to restore the state of pressed keys after the text is typed, i.e. presses the keys that were released at the beginning. Defaults to True.
  • exact forces typing all characters as explicit unicode (e.g. alt+codepoint or special events). If None, uses platform-specific suggested value.

[source]

Blocks the program execution until the given hotkey is pressed or, if given no parameters, blocks forever.

[source]

Returns a string representation of hotkey from the given key names, or the currently pressed keys if not given. This function:

  • normalizes names;
  • removes "left" and "right" prefixes;
  • replaces the "+" key name with "plus" to avoid ambiguity;
  • puts modifier keys first, in a standardized order;
  • sort remaining keys;
  • finally, joins everything with "+".

Example:

get_hotkey_name(['+', 'left ctrl', 'shift'])
# "ctrl+shift+plus"

[source]

Blocks until a keyboard event happens, then returns that event.

[source]

Blocks until a keyboard event happens, then returns that event's name or, if missing, its scan code.

[source]

Similar to read_key(), but blocks until the user presses and releases a hotkey (or single key), then returns a string representing the hotkey pressed.

Example:

read_hotkey()
# "ctrl+shift+p"

[source]

Given a sequence of events, tries to deduce what strings were typed. Strings are separated when a non-textual key is pressed (such as tab or enter). Characters are converted to uppercase according to shift and capslock status. If allow_backspace is True, backspaces remove the last character typed.

This function is a generator, so you can pass an infinite stream of events and convert them to strings in real time.

Note this functions is merely an heuristic. Windows for example keeps per- process keyboard state such as keyboard layout, and this information is not available for our hooks.

get_type_strings(record()) #-> ['This is what', 'I recorded', '']

[source]

Starts recording all keyboard events into a global variable, or the given queue if any. Returns the queue of events and the hooked function.

Use stop_recording() or unhook(hooked_function) to stop.

[source]

Stops the global recording of events and returns a list of the events captured.

[source]

Records all keyboard events from all keyboards until the user presses the given hotkey. Then returns the list of events recorded, of type keyboard.KeyboardEvent. Pairs well with play(events).

Note: this is a blocking function. Note: for more details on the keyboard hook and events see hook.

[source]

Plays a sequence of recorded events, maintaining the relative time intervals. If speed_factor is <= 0 then the actions are replayed as fast as the OS allows. Pairs well with record().

Note: the current keyboard state is cleared at the beginning and restored at the end of the function.

[source]

Invokes a callback every time a sequence of characters is typed (e.g. 'pet') and followed by a trigger key (e.g. space). Modifiers (e.g. alt, ctrl, shift) are ignored.

  • word the typed text to be matched. E.g. 'pet'.
  • callback is an argument-less function to be invoked each time the word is typed.
  • triggers is the list of keys that will cause a match to be checked. If the user presses some key that is not a character (len>1) and not in triggers, the characters so far will be discarded. By default the trigger is only space.
  • match_suffix defines if endings of words should also be checked instead of only whole words. E.g. if true, typing 'carpet'+space will trigger the listener for 'pet'. Defaults to false, only whole words are checked.
  • timeout is the maximum number of seconds between typed characters before the current word is discarded. Defaults to 2 seconds.

Returns the event handler created. To remove a word listener use remove_word_listener(word) or remove_word_listener(handler).

Note: all actions are performed on key down. Key up events are ignored. Note: word matches are case sensitive.

[source]

Removes a previously registered word listener. Accepts either the word used during registration (exact string) or the event handler returned by the add_word_listener or add_abbreviation functions.

[source]

Registers a hotkey that replaces one typed text with another. For example

add_abbreviation('tm', u'โ„ข')

Replaces every "tm" followed by a space with a โ„ข symbol (and no space). The replacement is done by sending backspace events.

  • match_suffix defines if endings of words should also be checked instead of only whole words. E.g. if true, typing 'carpet'+space will trigger the listener for 'pet'. Defaults to false, only whole words are checked.
  • timeout is the maximum number of seconds between typed characters before the current word is discarded. Defaults to 2 seconds.

For more details see add_word_listener.

[source]

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.

More Repositories

1

mouse

Hook and simulate global mouse events in pure Python
Python
861
star
2

steamgrid

Downloads images to fill your Steam grid view
Go
622
star
3

maze

Simple maze generator in Python
Python
62
star
4

bayesian

Utility for Bayesian reasoning
Python
37
star
5

server-sent-events

Python library for Server-Sent-Events
Python
36
star
6

minetesting

Client and mod for the Minetest game
Logos
15
star
7

hello_tls

Send TLS client hello in pure Python, for enumerating supported server cipher suites and protocols
Python
15
star
8

replace_me

Modify your own source code with this piece of Python black magic
Python
14
star
9

simplecrypto

Simple cryptographic library for hashing and encrypting
Python
12
star
10

gomeet

Go server to punch NAT holes
Go
11
star
11

carlo

Interactively plot streaming sequences of numbers
Python
9
star
12

structured-editor

Structured editor for general purpose programming languages
Python
8
star
13

gifencoder

The missing method gif.Encode in Go's library
Go
8
star
14

marktex

Markdown to Latex for thesis, reports, and presentations
Python
8
star
15

gogame

HTML5 version of the Go board game
HTML
7
star
16

cryptopals-challenge

My solutions to challenges at https://cryptopals.com/
Python
6
star
17

framebuffer

Simple and low level C graphics library
C
6
star
18

stack

A toy stack based language
Go
6
star
19

kindle-collections

Automatically generates collections from your directory structure
Go
5
star
20

listregex

Apply regular expressions to lists of arbitrary objects
Python
5
star
21

kahn

Simple and flexible pipeline system for Python
Python
5
star
22

8puzzle

Python solution to sliding 8-puzzle
Python
4
star
23

gl4

Micro game library, v4
JavaScript
4
star
24

cloud_backup_script

Uses rsync to upload immutable files (photos, videos, etc) to a Hetzner Storage Box
Shell
4
star
25

feeder

Dead simple local RSS feed reader
Python
4
star
26

f

The worst Unix program.
Python
4
star
27

ecc

Textbook Elliptic Curve Cryptography for Python and C
C
3
star
28

monty

Library for exploring discrete distributions
Python
3
star
29

shamir

Shamir secret sharing algorithm with threshold detection
Python
3
star
30

markov

Markov chain library to create new data from examples
Python
3
star
31

sciplot

Pythonic data visualization tool
Python
3
star
32

flappy_doge_2048

Tiny, buggy game. Because why not?
JavaScript
3
star
33

typist

Records typing statistics
Python
3
star
34

playreduce

Game based on creating binary finite field reduction algorithms
HTML
3
star
35

flappybot

Auto player for the FlapMMO game
JavaScript
3
star
36

background

Library for Python applications that run in the background
Python
3
star
37

blackcrypto

Library of cryptanalysis tools
Python
2
star
38

web-interact

Two-layer server model for interactivity based on Server-Sent-Events
JavaScript
2
star
39

t

Todo list manager
Python
2
star
40

bop

Experimental Web Framework with Server-Sent-Events
Python
2
star
41

graphql

Basic implementation of GraphQL using in-memory objects
Python
2
star
42

room

Doom-like raytracer
HTML
2
star
43

workspace

Manages programming projects
Python
2
star
44

pycalc

Calculator server with measure unit and Python support
Python
2
star
45

voltorb_flip_solver

Solver for the Pokemon HeartGold game Voltorb Flip
Python
2
star
46

boppreh.github.io

Source code for my homepage
JavaScript
2
star
47

adventofcode_2020

Python
2
star
48

ludum_dare39

Failed to make a game, but the engine rocks!
HTML
2
star
49

speedreader

My try at "Rapid serial visual presentation" (flashing words)
JavaScript
2
star
50

sprawl

Go reimagined as a strategy game
HTML
2
star
51

frango

Authentication system for web services
HTML
2
star
52

adventofcode

My solutions to http://adventofcode.com
Python
2
star
53

gitstatus

Background app for tracking status of local Git repositories
Python
2
star
54

shell

Web-based structured console terminal
HTML
2
star
55

anakata

Anakata is a 4D, tiled, command line puzzle game in Python
Python
2
star
56

jsmatrixboard

Library for highly-interactive matrix-like structures
HTML
2
star
57

goutils

Small Go functions for the everyday programmer
Go
2
star
58

packager

Python script for converting existing projects into PyPi packages
Python
2
star
59

canvasengine

HTML5 Canvas hooks for game bots
JavaScript
2
star
60

poly

Study of polynomials and recurrence relations
Python
2
star
61

gohandlers

Library of HTTP handlers
Go
2
star
62

ppackager

Manage Python packages
Python
2
star
63

gallery

Extracts images from websites and displays in a gallery
Python
2
star
64

gowiki

Very simple wiki server in Go
Go
2
star
65

reduction-circuit

Draws a XOR circuit to perform binary polynomial reduction
HTML
2
star
66

inflist

Infinite lists in Python using lazy evaluation
Python
2
star
67

go-ui

High level Go library for graphical user interfaces
Go
2
star
68

statistical

Small tool for simple statistical tests on samples
2
star
69

dotfiles

My configuration files
Vim Script
2
star
70

telescoping_text

Text with variable amount of details
CSS
2
star
71

dashboard

Attempt at a desktop dashboard with useful functions
Python
2
star
72

console

Cross platform library for simple command line applications
Python
2
star
73

derivative

Library for calculating derivatives using dual numbers
Python
2
star
74

websentinel

Watches webpages for changes and keyword occurences
Python
2
star
75

ludum_dare28

Entry for the 28th Ludum Dare compo
JavaScript
2
star
76

dictfs

Wraps the file system in a dictionary like access structure
Python
2
star
77

ledhero

Guitar-hero like game using only the keyboard LEDs as display
Python
2
star
78

extract_by_pattern

Extract data from texts with no clear field separator
Python
2
star
79

matrix

Pythonic 2D matrix data type
Python
2
star
80

2048bot

Bot for playing the game "2048"
Python
2
star
81

fsm

Fast and simple Finite State Machine library
Python
2
star
82

manual_file_classifier

(k)eep, (d)elete, (r)ename or (m)ove?
Python
2
star
83

switch

Background application responsible for starting and stopping other applications
Python
2
star
84

autokeyboard

Automate everything keyboard
Python
1
star
85

toon_tools

Adds a prefix letter to all files in a given folder
Go
1
star
86

frango-app

Java
1
star
87

activity

Watches, stores and reports user activity on the computer
Python
1
star
88

word2vec_bin_parser

Tiny Python library for parsing Word2Vec .bin embeddings
Python
1
star
89

easier-as3

Tiny functions for common tasks
ActionScript
1
star
90

constraint_propagation

Solver for assigning values to cells via constraint propagation (e.g. Sudoku, Zebra puzzle, seating plan)
Python
1
star
91

attachment

Downloads email attachments you receive and emails attachments you upload
Python
1
star
92

cinema

Finds subtitles and starts playing a movie
Python
1
star
93

symcalc

Symbolic calculator using Python's sympy package
Python
1
star
94

doorman

Notifies when computers enter and exit the wireless network
Python
1
star