directkeys


Namedirectkeys JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://github.com/WigoWigo10/keyboard
SummaryA modern and robust keyboard hooking and simulation library for Windows and Linux, focusing on low-level control.
upload_time2025-10-11 19:49:24
maintainerNone
docs_urlNone
authorWigoWigo
requires_pythonNone
licenseMIT
keywords directkeys keyboard hook simulate hotkey low-level win32 sendinput
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            
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](#directkeys.record) and [play](#directkeys.play), [add_abbreviation](#directkeys.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](https://github.com/boppreh/mouse) (`pip install mouse`).

## Usage

Install the [PyPI package](https://pypi.python.org/pypi/keyboard/):

    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](https://github.com/boppreh/keyboard/archive/master.zip) into your project folder.

Then check the [API docs below](https://github.com/boppreh/keyboard#api) to see what features are available.


## Example

Use as library:

```py
import directkeys

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

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

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

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

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

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

# Type @@ then press space to replace with abbreviation.
directkeys.add_abbreviation('@@', 'my.long.email@example.com')

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

Use as standalone module:

```bash
# 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](https://github.com/boppreh/keyboard/issues/21)
- Media keys on Linux may appear nameless (scan-code only) or not at all. [#20](https://github.com/boppreh/keyboard/issues/20)
- Key suppression/blocking only available on Windows. [#22](https://github.com/boppreh/keyboard/issues/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

```py
import directkeys
directkeys.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
directkeys.wait()

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

### Waiting for a key press one time

```py
import directkeys

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

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

### Repeatedly waiting for a key press

```py
import directkeys

# Don't do this!
#
#while True:
#    if directkeys.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:
    directkeys.wait('space')
    print('space was pressed! Waiting on it again...')

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

### Invoking code when an event happens

```py
import directkeys

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

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

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

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

### 'Press any key to continue'

```py
# Don't do this! The `keyboard` module is meant for global events, even when your program is not in focus.
#import directkeys
#print('Press any key to continue...')
#directkeys.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
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/WigoWigo10/keyboard",
    "name": "directkeys",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "directkeys keyboard hook simulate hotkey low-level win32 sendinput",
    "author": "WigoWigo",
    "author_email": "hiigoor93@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/ec/5e/34be562457584a76046d79eaa962e1fd00113d92a49d991c77064a1b2db8/directkeys-1.0.0.tar.gz",
    "platform": null,
    "description": "\r\nkeyboard\r\n========\r\n\r\nTake full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more.\r\n\r\n## Features\r\n\r\n- **Global event hook** on all keyboards (captures keys regardless of focus).\r\n- **Listen** and **send** keyboard events.\r\n- Works with **Windows** and **Linux** (requires sudo), with experimental **OS X** support (thanks @glitchassassin!).\r\n- **Pure Python**, no C modules to be compiled.\r\n- **Zero dependencies**. Trivial to install and deploy, just copy the files.\r\n- **Python 2 and 3**.\r\n- Complex hotkey support (e.g. `ctrl+shift+m, ctrl+space`) with controllable timeout.\r\n- Includes **high level API** (e.g. [record](#directkeys.record) and [play](#directkeys.play), [add_abbreviation](#directkeys.add_abbreviation)).\r\n- Maps keys as they actually are in your layout, with **full internationalization support** (e.g. `Ctrl+\u00e7`).\r\n- Events automatically captured in separate thread, doesn't block main program.\r\n- Tested and documented.\r\n- Doesn't break accented dead keys (I'm looking at you, pyHook).\r\n- Mouse support available via project [mouse](https://github.com/boppreh/mouse) (`pip install mouse`).\r\n\r\n## Usage\r\n\r\nInstall the [PyPI package](https://pypi.python.org/pypi/keyboard/):\r\n\r\n    pip install keyboard\r\n\r\nor clone the repository (no installation required, source files are sufficient):\r\n\r\n    git clone https://github.com/boppreh/keyboard\r\n\r\nor [download and extract the zip](https://github.com/boppreh/keyboard/archive/master.zip) into your project folder.\r\n\r\nThen check the [API docs below](https://github.com/boppreh/keyboard#api) to see what features are available.\r\n\r\n\r\n## Example\r\n\r\nUse as library:\r\n\r\n```py\r\nimport directkeys\r\n\r\ndirectkeys.press_and_release('shift+s, space')\r\n\r\ndirectkeys.write('The quick brown fox jumps over the lazy dog.')\r\n\r\ndirectkeys.add_hotkey('ctrl+shift+a', print, args=('triggered', 'hotkey'))\r\n\r\n# Press PAGE UP then PAGE DOWN to type \"foobar\".\r\ndirectkeys.add_hotkey('page up, page down', lambda: directkeys.write('foobar'))\r\n\r\n# Blocks until you press esc.\r\ndirectkeys.wait('esc')\r\n\r\n# Record events until 'esc' is pressed.\r\nrecorded = directkeys.record(until='esc')\r\n# Then replay back at three times the speed.\r\ndirectkeys.play(recorded, speed_factor=3)\r\n\r\n# Type @@ then press space to replace with abbreviation.\r\ndirectkeys.add_abbreviation('@@', 'my.long.email@example.com')\r\n\r\n# Block forever, like `while True`.\r\ndirectkeys.wait()\r\n```\r\n\r\nUse as standalone module:\r\n\r\n```bash\r\n# Save JSON events to a file until interrupted:\r\npython -m keyboard > events.txt\r\n\r\ncat events.txt\r\n# {\"event_type\": \"down\", \"scan_code\": 25, \"name\": \"p\", \"time\": 1622447562.2994788, \"is_keypad\": false}\r\n# {\"event_type\": \"up\", \"scan_code\": 25, \"name\": \"p\", \"time\": 1622447562.431007, \"is_keypad\": false}\r\n# ...\r\n\r\n# Replay events\r\npython -m keyboard < events.txt\r\n```\r\n\r\n## Known limitations:\r\n\r\n- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21)\r\n- Media keys on Linux may appear nameless (scan-code only) or not at all. [#20](https://github.com/boppreh/keyboard/issues/20)\r\n- Key suppression/blocking only available on Windows. [#22](https://github.com/boppreh/keyboard/issues/22)\r\n- To avoid depending on X, the Linux parts reads raw device files (`/dev/input/input*`) but this requires root.\r\n- Other applications, such as some games, may register hooks that swallow all key events. In this case `keyboard` will be unable to report events.\r\n- This program makes no attempt to hide itself, so don't use it for keyloggers or online gaming bots. Be responsible.\r\n- 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.\r\n\r\n## Common patterns and mistakes\r\n\r\n### Preventing the program from closing\r\n\r\n```py\r\nimport directkeys\r\ndirectkeys.add_hotkey('space', lambda: print('space was pressed!'))\r\n# If the program finishes, the hotkey is not in effect anymore.\r\n\r\n# Don't do this! This will use 100% of your CPU.\r\n#while True: pass\r\n\r\n# Use this instead\r\ndirectkeys.wait()\r\n\r\n# or this\r\nimport time\r\nwhile True:\r\n    time.sleep(1000000)\r\n```\r\n\r\n### Waiting for a key press one time\r\n\r\n```py\r\nimport directkeys\r\n\r\n# Don't do this! This will use 100% of your CPU until you press the key.\r\n#\r\n#while not directkeys.is_pressed('space'):\r\n#    continue\r\n#print('space was pressed, continuing...')\r\n\r\n# Do this instead\r\ndirectkeys.wait('space')\r\nprint('space was pressed, continuing...')\r\n```\r\n\r\n### Repeatedly waiting for a key press\r\n\r\n```py\r\nimport directkeys\r\n\r\n# Don't do this!\r\n#\r\n#while True:\r\n#    if directkeys.is_pressed('space'):\r\n#        print('space was pressed!')\r\n#\r\n# This will use 100% of your CPU and print the message many times.\r\n\r\n# Do this instead\r\nwhile True:\r\n    directkeys.wait('space')\r\n    print('space was pressed! Waiting on it again...')\r\n\r\n# or this\r\ndirectkeys.add_hotkey('space', lambda: print('space was pressed!'))\r\ndirectkeys.wait()\r\n```\r\n\r\n### Invoking code when an event happens\r\n\r\n```py\r\nimport directkeys\r\n\r\n# Don't do this! This will call `print('space')` immediately then fail when the key is actually pressed.\r\n#directkeys.add_hotkey('space', print('space was pressed'))\r\n\r\n# Do this instead\r\ndirectkeys.add_hotkey('space', lambda: print('space was pressed'))\r\n\r\n# or this\r\ndef on_space():\r\n    print('space was pressed')\r\ndirectkeys.add_hotkey('space', on_space)\r\n\r\n# or this\r\nwhile True:\r\n    # Wait for the next event.\r\n    event = directkeys.read_event()\r\n    if event.event_type == directkeys.KEY_DOWN and event.name == 'space':\r\n        print('space was pressed')\r\n```\r\n\r\n### 'Press any key to continue'\r\n\r\n```py\r\n# Don't do this! The `keyboard` module is meant for global events, even when your program is not in focus.\r\n#import directkeys\r\n#print('Press any key to continue...')\r\n#directkeys.get_event()\r\n\r\n# Do this instead\r\ninput('Press enter to continue...')\r\n\r\n# Or one of the suggestions from here\r\n# https://stackoverflow.com/questions/983354/how-to-make-a-script-wait-for-a-pressed-key\r\n```\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A modern and robust keyboard hooking and simulation library for Windows and Linux, focusing on low-level control.",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/WigoWigo10/keyboard"
    },
    "split_keywords": [
        "directkeys",
        "keyboard",
        "hook",
        "simulate",
        "hotkey",
        "low-level",
        "win32",
        "sendinput"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "75feb75e1f02925b999281e40d3f9bf94e93d8e72c58cfb34033aac0546cfbe9",
                "md5": "ac0ec4fcea3a0258c923589a402a3fc0",
                "sha256": "c60c1ee8a4d62d8da6a2e2fa506468dc6bc3941015fb7d23751237b36d27d99c"
            },
            "downloads": -1,
            "filename": "directkeys-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ac0ec4fcea3a0258c923589a402a3fc0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 55876,
            "upload_time": "2025-10-11T19:49:23",
            "upload_time_iso_8601": "2025-10-11T19:49:23.089999Z",
            "url": "https://files.pythonhosted.org/packages/75/fe/b75e1f02925b999281e40d3f9bf94e93d8e72c58cfb34033aac0546cfbe9/directkeys-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ec5e34be562457584a76046d79eaa962e1fd00113d92a49d991c77064a1b2db8",
                "md5": "8d89d307871085dd84ba6a74b5de15c2",
                "sha256": "f3aed8d054370c6050d229f120325676ebef2add90e12f844158b9771cd46134"
            },
            "downloads": -1,
            "filename": "directkeys-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8d89d307871085dd84ba6a74b5de15c2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 68558,
            "upload_time": "2025-10-11T19:49:24",
            "upload_time_iso_8601": "2025-10-11T19:49:24.623128Z",
            "url": "https://files.pythonhosted.org/packages/ec/5e/34be562457584a76046d79eaa962e1fd00113d92a49d991c77064a1b2db8/directkeys-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-11 19:49:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "WigoWigo10",
    "github_project": "keyboard",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": false,
    "lcname": "directkeys"
}
        
Elapsed time: 2.20840s