Can't figure out how to install Pynput

I’ve been working on a project which involves taking in user input in the Python console, and I’d like to be able to detect each individual key press for every key. In my attempts to do this, I’ve found pynput and it seems this code should enable me to do this:

from pynput import keyboard

def on_press(key):
	print(key, "pressed")

def on_release(key):
	print(key, "released")

_input = keyboard.Listener(on_press=on_press, on_release=on_release)
_input.start()

(Here’s a demo Repl)
This code isn’t the issue though, getting it’s getting it to run in the first place.

When I run this code, I get this error:

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    from pynput import keyboard
ModuleNotFoundError: No module named 'pynput'

Which is because pynput has not successfully been installed (best I understand). So I’ve tried running the command poetry add pynput in the shell which results in the error below (collapsed because it’s pretty long).

Full error details
~/Pynput-Issue$ poetry add pynput
Using version ^1.7.6 for pynput

Updating dependencies
Resolving dependencies... (1.0s)

Package operations: 2 installs, 0 updates, 0 removals

  • Installing evdev (1.6.1): Failed

  EnvCommandError

  Command ['/home/runner/Pynput-Issue/venv/bin/pip', 'install', '--no-deps', 'https://files.pythonhosted.org/packages/05/50/629b011a7f61cb2fca754ea8631575784bf8605a1ec4d6970a010bc54e2b/evdev-1.6.1.tar.gz#sha256=299db8628cc73b237fc1cc57d3c2948faa0756e2a58b6194b5bf81dc2081f1e3'] errored with the following return code 1, and output: 
  Looking in indexes: https://package-proxy.replit.com/pypi/simple/
  Collecting https://files.pythonhosted.org/packages/05/50/629b011a7f61cb2fca754ea8631575784bf8605a1ec4d6970a010bc54e2b/evdev-1.6.1.tar.gz#sha256=299db8628cc73b237fc1cc57d3c2948faa0756e2a58b6194b5bf81dc2081f1e3
    Using cached evdev-1.6.1.tar.gz (26 kB)
  Using legacy 'setup.py install' for evdev, since package 'wheel' is not installed.
  WARNING: pip is using a content-addressable pool to install files from. This experimental feature is enabled through --use-feature=content-addressable-pool and it is not ready for production.
  Installing collected packages: evdev
      Running setup.py install for evdev: started
      Running setup.py install for evdev: finished with status 'error'
      ERROR: Command errored out with exit status 1:
       command: /home/runner/Pynput-Issue/venv/bin/python3 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-v44ejtsn/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-v44ejtsn/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-6ohp51yx/install-record.txt --single-version-externally-managed --compile --install-headers /home/runner/Pynput-Issue/venv/include/site/python3.10/evdev
           cwd: /tmp/pip-req-build-v44ejtsn/
      Complete output (39 lines):
      running install
      /home/runner/Pynput-Issue/venv/lib/python3.10/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        warnings.warn(
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-cpython-310
      creating build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/__init__.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/device.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/ecodes.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/eventio.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/eventio_async.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/events.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/evtest.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/ff.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/genecodes.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/uinput.py -> build/lib.linux-x86_64-cpython-310/evdev
      copying evdev/util.py -> build/lib.linux-x86_64-cpython-310/evdev
      running build_ext
      running build_ecodes
      The 'linux/input.h' and 'linux/input-event-codes.h' include files
      are missing. You will have to install the kernel header files in
      order to continue:
      
          yum install kernel-headers-$(uname -r)
          apt-get install linux-headers-$(uname -r)
          emerge sys-kernel/linux-headers
          pacman -S kernel-headers
      
      In case they are installed in a non-standard location, you may use
      the '--evdev-headers' option to specify one or more colon-separated
      paths. For example:
      
          python setup.py \
            build \
            build_ecodes --evdev-headers path/input.h:path/input-event-codes.h \
            build_ext --include-dirs  path/ \
            install
      ----------------------------------------
  ERROR: Command errored out with exit status 1: /home/runner/Pynput-Issue/venv/bin/python3 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-v44ejtsn/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-v44ejtsn/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-6ohp51yx/install-record.txt --single-version-externally-managed --compile --install-headers /home/runner/Pynput-Issue/venv/include/site/python3.10/evdev Check the logs for full command output.
  

  at venv/lib/python3.10/site-packages/poetry/utils/env.py:1195 in _run
      1191│                 output = subprocess.check_output(
      1192│                     cmd, stderr=subprocess.STDOUT, **kwargs
      1193│                 )
      1194│         except CalledProcessError as e:
    → 1195│             raise EnvCommandError(e, input=input_)
      1196│ 
      1197│         return decode(output)
      1198│ 
      1199│     def execute(self, bin, *args, **kwargs):


Failed to add packages, reverting the pyproject.toml file to its original content.

Hopefully someone can help me get this installed correctly! :smile:

1 Like

Take a look at this
https://pynput.readthedocs.io/en/latest/

https://replit.com/talk/ask/How-do-I-get-pynput-to-work/25852

1 Like

Thanks, so I probably need to add some stuff toreplit.nix then… I’ll try some stuff, but if anyone knows exactly what I should be doing is very much appreciate some help :smile:

1 Like

ok so iirc this is because this is a legacy package that uploads to pypi with a special file called setup.py. If installing via nix works, that’s probably why since they probably had to use a different method to upload to nix.

1 Like

I’ve been trying to address the errors occurring.

poetry add wheel works fine, so does adding pkgs.python310Packages.wheel, but neither fixes the error.

I’ve tried adding pkgs.linuxHeaders, which also didn’t help.

I then managed to find these two topics: Can't install pynput and Unable to add pynput to environment, but neither has helped too much. The first recommends using the package pynput-robocrop from the packages tab, however this package no longer exists, I did find pynput-robocrop-fork which I assume is probably the same or next to. The issue with this is it opens an output window rather than just using the console for everything.

I think I should mention what I’m actually trying to do, I think pynput might actually not be what I’m looking for, I’m trying to read individual key presses (as in ‘on release’) in the Python console. I know this is possible since I’m pretty sure I’ve seen Repls that do this, so I’m going to search for a Repl and try to find a working one to figure it out from.

1 Like

It has too, as far as I understand, replit only passes text when the console is used, but the vnc screen can pass keypresses and other more advanced inputs.

Edit: can you link a repl that takes key inputs? I would like to know how they did it.

2 Likes

I’ve figured it out, there’s a package called getkey which works fine! Here’s a demo.

from threading import Thread
from getkey import getkey, keys
from time import sleep


class KeyboardThread(Thread):
	def __init__(self):
		super(KeyboardThread, self).__init__(name="input-thread")
		self.start()

	def run(self):
		while True:
			print(getkey(), end="", flush=True)


input_thread = KeyboardThread()

while True:
	sleep(1)
2 Likes

lol yeah I probably should have said one works, but I wanted to figure out once and for all the funky py packages XD

That works as most of the working ones on replit do, replit turns keystrokes when the console is accepting input into text. So the program just has to constantly accept input and then translate the keys. Great job on finding the package!

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.