How to Control your Keyboard in Python

Learn how to control your keyboard in Python: press keys, type text, create global hotkeys, expand snippets, record/replay macros, and compare keyboard, pynput, and PyAutoGUI.
  · 7 min read · Updated may 2026 · General Python Tutorials

Confused by complex code? Let our AI-powered Code Explainer demystify it for you. Try it out!

Python can simulate keyboard input, register global shortcuts, expand abbreviations, and listen for key events. This is useful for desktop automation, small productivity tools, accessibility helpers, game tooling, testing workflows, and scripts that fill repetitive forms.

In this tutorial, we will use the keyboard package to control the keyboard in Python. The original examples still work in many setups, but a few things are worth saying up front:

  • The keyboard package is most convenient on Windows and Linux. On Linux, global hooks usually need root privileges or access to /dev/input.
  • macOS support is limited. If you mainly target macOS, pynput or PyAutoGUI may be a smoother choice.
  • Global keyboard hooks do not usually work inside hosted notebooks, containers, or headless servers. Test them on your own desktop.
  • Do not record or intercept other people's keystrokes. Use these tools only for automation you own or have permission to run.

We will cover pressing keys, typing text, holding keys, registering hotkeys, expanding text snippets, recording keyboard events, replaying macros, and a safer complete script that uses dry-run mode by default.

Related: How to Control your Mouse in Python.

Installing the Keyboard Package

Install it with pip:

pip install keyboard

On Linux, if you get permission errors while listening for global events, try running your script with sudo or configure proper input-device permissions for your user:

sudo python script.py

Then import it:

import keyboard

Pressing and Releasing Keys

The simplest action is pressing and releasing one key:

import keyboard

keyboard.press_and_release("space")
keyboard.press_and_release("enter")

press_and_release() is explicit and easy to read. The shorter send() function does the same thing:

keyboard.send("space")

You can also send keyboard shortcuts:

keyboard.send("ctrl+c")
keyboard.send("ctrl+v")
keyboard.send("windows+d")  # show desktop on Windows

For multi-step shortcuts, separate steps with a comma. For example, this sends Alt+F4, then Enter:

# Careful: this can close the active window.
keyboard.send("alt+f4, enter")

When automating real applications, always make sure the correct window is focused before sending keys. Keyboard automation sends events to the active application, not to a hidden window you choose by name.

Holding a Key Down

Sometimes you need to hold a key, do something else, then release it. Use press() and release():

import time
import keyboard

keyboard.press("shift")
time.sleep(0.5)
keyboard.release("shift")

You can also use send() with do_press and do_release:

keyboard.send("ctrl", do_release=False)
# do something while Ctrl is held
keyboard.send("ctrl", do_press=False)

Typing Text

To type text, use write():

import keyboard

keyboard.write("Python keyboard automation is useful.", delay=0.03)

The delay argument is the delay between characters. A small delay often makes automation more reliable because some apps do not handle very fast artificial input well.

For example, this waits three seconds so you can focus a text editor, then types a short message:

import time
import keyboard

print("Focus your text editor. Typing starts in 3 seconds...")
time.sleep(3)
keyboard.write("Hello from Python!", delay=0.05)

Checking Whether a Key Is Pressed

You can check the state of a key with is_pressed():

import keyboard

if keyboard.is_pressed("ctrl"):
    print("Ctrl is currently pressed")

A common pattern is a small loop that runs until the user presses Esc:

import time
import keyboard

print("Press Esc to stop.")
while not keyboard.is_pressed("esc"):
    print("Working...")
    time.sleep(1)

For a cleaner one-time wait, use wait():

keyboard.wait("esc")
print("Esc was pressed")

Registering Global Hotkeys

add_hotkey() lets you run a callback whenever a key combination is pressed:

import keyboard

keyboard.add_hotkey("ctrl+alt+h", lambda: print("Hello from a hotkey!"))
print("Press Ctrl+Alt+H, or press Esc to exit.")
keyboard.wait("esc")
keyboard.unhook_all()

The callback runs in a separate thread. Keep hotkey callbacks short. If your callback needs to do heavy work, put that work into a queue or start another thread/process yourself.

You can also remove one hotkey by keeping the handler returned by add_hotkey():

handler = keyboard.add_hotkey("ctrl+shift+x", lambda: print("Shortcut fired"))

# later
keyboard.remove_hotkey(handler)

Text Expansion with Abbreviations

Text expansion is one of the handiest features. The following expands @email into an email address after you type it and press Space:

import keyboard

keyboard.add_abbreviation("@email", "name@example.com")
keyboard.add_abbreviation("@addr", "221B Baker Street, London")

print("Type @email or @addr followed by Space. Press Esc to quit.")
keyboard.wait("esc")
keyboard.unhook_all()

This is useful for snippets you type often: email addresses, canned replies, signatures, support links, or test data.

Listening to Keyboard Events

You can listen for press and release events. For example, this prints released key names until you press Esc:

import keyboard


def on_key_release(event):
    print(event.name)
    if event.name == "esc":
        keyboard.unhook_all()


keyboard.on_release(on_key_release)
keyboard.wait("esc")

Again, only do this in programs where the user understands what is being captured. Keyboard listeners can see sensitive input if you write them carelessly.

Recording and Replaying Keyboard Events

record() captures keyboard events until a stop key is pressed. play() replays them:

import keyboard

print("Recording. Press Esc to stop.")
events = keyboard.record("esc")

print("Typed strings:", list(keyboard.get_typed_strings(events)))

answer = input("Replay the recorded events? [y/N] ").strip().lower()
if answer == "y":
    keyboard.play(events)

Replaying events is powerful, but it can also do the wrong thing very quickly if the wrong window is focused. In real scripts, add a countdown and ask for confirmation before replaying a macro.

A Safer Complete Example

The complete code below is written to be safer for learning and testing. By default, it runs in dry-run mode, meaning it only prints what it would do. Add --execute on your own desktop when you actually want to send or listen to keyboard events.

Save it as keyboard_controller_2026.py:

# Preview actions only
python keyboard_controller_2026.py typing
python keyboard_controller_2026.py hotkeys
python keyboard_controller_2026.py record

# Actually run on your local desktop
python keyboard_controller_2026.py typing --execute
python keyboard_controller_2026.py hotkeys --execute
python keyboard_controller_2026.py record --execute

The script is available in the full code section at the end of the tutorial.

When to Use pynput or PyAutoGUI Instead

The keyboard package is convenient for global hotkeys and quick scripts. Still, it is not the only choice:

  • Use pynput if you want a maintained library for monitoring and controlling keyboard/mouse input, especially across platforms.
  • Use PyAutoGUI if your goal is broader GUI automation: clicking, screenshots, locating images on screen, and typing into active windows.

Here is the basic pynput style for typing:

from pynput.keyboard import Controller, Key

keyboard = Controller()
keyboard.type("Hello from pynput!")
keyboard.press(Key.enter)
keyboard.release(Key.enter)

And here is the basic PyAutoGUI style:

import pyautogui

pyautogui.write("Hello from PyAutoGUI!", interval=0.03)
pyautogui.hotkey("ctrl", "s")

If you need global hotkeys and abbreviation expansion, keyboard is pleasant to use. If you need cross-platform input control with a more actively maintained package, check pynput. If you need full GUI automation, use PyAutoGUI.

Troubleshooting

Nothing happens when I send keys

Make sure the target application is focused. Try adding a short countdown before sending keys:

import time
print("Focus the target window...")
time.sleep(3)

Linux says permission denied

Global keyboard hooks usually need root privileges or access to input devices. For a quick test, run with sudo. For a proper setup, configure input group permissions for your environment.

It does not work in Jupyter, Docker, or a remote server

That is expected. Keyboard automation needs access to the local desktop session. Run it as a normal Python script on your machine.

Some key names do not work

Print the event names first:

import keyboard

keyboard.on_press(lambda event: print(event.name))
keyboard.wait("esc")

Then use the printed names in send(), press_and_release(), or add_hotkey().

Conclusion

The keyboard package makes it easy to automate keyboard input in Python: press keys, type text, hold modifiers, register shortcuts, expand snippets, and record simple macros. Use it for your own automation tasks, keep scripts easy to stop, and be careful with recording or replaying events.

For larger desktop automation projects, also look at PyAutoGUI and pynput.

Learn also: How to Convert Python Files into Executables.

Happy Coding ♥

Save time and energy with our Python Code Generator. Why start from scratch when you can generate? Give it a try!

View Full Code Generate Python Code
Sharing is caring!



Read Also



Comment panel

    Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!