Simple keylogger with Pynput in Python

In this tutorial we will focus on logging keyboard events using the Pynput library in Python. I have a Raspberry Pi that I use without a keyboard or mouse, and that is plugged in to my TV. As I mentioned in this tutorial on xdotool, my end goal is to play old games with RetroPie. The only problem is that it’s impossible to control the games over SSH. One possible solution that I found, is to use my laptop to send keyboard events to the Rasperry Pi’s OS.

There are two main parts to this:

  • The Raspberry Pi must run some kind of server that listens to messages from a client (my laptop) and generates corresponding events on the OS level. I found that this is best done using python-uinput, and will write a tutorial about it in the future.
  • The laptop must send a message to the Raspberry Pi every time a key is pressed or released.

In this article we’re going to learn how to log keyboard events with Pynput in Python 3. Of course, the applications for a keylogger like this range way beyond the one I’m talking about here. Keep in mind that some applications can be malicious and illegal; those are not the point of this article and I do not encourage such uses.

Install the tools

I will be using Mac OS X and the Pynput package with Python 3. You can use Windows or Linux too, the program should be pretty much the same. It is also possible to use Python 2.x, in which case you can feel free to skip the next part about installing Python 3.

Python 3

On OS X, you can use Homebrew to install Python 3. Run the following command to install Homebrew if it’s not installed yet:

You will need to give your confirmation before the installation starts. Once it is installed, you’ll have to add Homebrew to your PATH variable. The PATH is where your OS looks for executables when you type a command. You can see what folders are part of your PATH by typing:

Add /usr/local/sbin and /usr/local/bin to your PATH if they’re not part of it yet, by adding this line to the file ~/.profile or ~/.bashrc:


Now you can install Python 3 by running brew install python3. This installation may take a few minutes. Once it is finished, make sure it is installed properly by starting a Python 3 shell; type python3.


Pynput is a Python package that allows you to control and monitor the keyboard and mouse. You can install it with Pip, the Python package manager that was installed with Python. Run the command:  pip3 install pynput.

Write the program

Basic program

Let’s write a program, that will listen to any event on the keyboard. We need to listen to “press” and “release” events, which correspond to a key being pressed down, and a key being released. To do so, we just need to define the functions on_press() and on_release(), and create a Listener with those functions:

When a key is pressed or release, we just print it to the standard output. When the key escape is released (which string description is Key.esc), we exit the program. It’s always important to implement a clean way to exit a program. In this case, it makes sense to detect a particular key and use it as an exit key.

Start the script

To run this program, you can type python3 Although, you’ll see that only special keys are logged, such as Command, Ctrl, Shift, etc… To log every key, you’ll have to run the program with root privileges, by typing sudo python3 This is because OS X considers it unsafe to give full access to the keyboard to normal users (which is understandable!).

You can also run the program as an executable, thanks to the shebang on the first line. However, you’ll first have to give execute rights to the file, by running  sudo chmod u+x You can also use only +x instead of u+x, but it’s generally safer to only give rights to the necessary user, instead of everyone. Then, execute the script by typing sudo ./

When the script is running, it will log the pressed and released keys to the console, even if the terminal window is not on focus anymore:

Detect special characters vs alphanumeric characters

Types of keys

One thing that can be annoying if you’re gonna use this keylogger like I want to, to send the typed keys to a server, is that normal characters such as letters and numbers, are printed with extra single quotes (‘a’ instead of a). To change this, we’ll add a function that checks what type of key has been pressed. It is simply done by checking the type of object of the key. Special characters are of type keyboard.Key, while normal characters are keyboard.KeyCode. To prove this, just add the following line to on_press() and/or on_release():

Now run the script and type both normal and special characters; the script will log the type of each:

Modify the code

Let’s write a function get_key_name(), that will check the type of the key. For a normal key it will return key.char, which won’t have extra single quotes. For other keys, it will print the name of the key (such as Key.cmd, Key.alt, Key.ctrl…)

Final code

The final script is the following:

If you run it, you’ll see that keys are now properly logger, until we press the escape key:


As you can see, creating a simple key logger is very easy with Pynput. There are many ways to expand this script to make a more advanced application:

  • Write the keys to a log file, so that you can keep a trace of them.
  • Send the keys to a server that will process them. In my case, I send the keys to a server on the Raspberry Pi, that generates the corresponding events locally.
  • Feel free to find other ideas and share them in the comments below!

Again, I know there can be malicious uses of a key logger, and I do not approve of them. This tutorial has a purely educational mean.

Be the first to comment

%d bloggers like this: