Turn your code into any language with our Code Converter. It's the ultimate tool for multi-language programming. Start converting now!
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:
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.
Install it with pip:
pip install keyboardOn 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.pyThen import it:
import keyboardThe 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 WindowsFor 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.
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)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)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")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 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.
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.
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.
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 --executeThe script is available in the full code section at the end of the tutorial.
The keyboard package is convenient for global hotkeys and quick scripts. Still, it is not the only choice:
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.
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)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.
That is expected. Keyboard automation needs access to the local desktop session. Run it as a normal Python script on your machine.
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().
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 ♥
Take the stress out of learning Python. Meet our Python Code Assistant – your new coding buddy. Give it a whirl!
View Full Code Explain The Code for MeJoin 50,000+ Python Programmers & Enthusiasts like you!
Email address Subscribe This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.Ethical Hacking with Python EBook
Web Security with Python EBook
Cryptography with Python EBook
Practical Python PDF Processing EBook
Real-Time Traffic Monitoring System with YOLOv9 eBook
Mastering YOLO: Build an Automatic Number Plate Recognition System
© 2026 The Python Code. All rights reserved.
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!