2

I'm trying to run on an embedded computer (hence with no display) a module using pynput package. I'm connected via ssh to the embedded computer (which is on Linux) and when I try to run the script I get this error :

Traceback (most recent call last):
  File "/home/remi/robot-artificial-intelligence/install/ea_maintenance_mode_manager/lib/ea_maintenance_mode_manager/maintenance_mode", line 33, in <module>
    sys.exit(load_entry_point('ea-maintenance-mode-manager==0.1.0', 'console_scripts', 'maintenance_mode')())
  File "/home/remi/robot-artificial-intelligence/install/ea_maintenance_mode_manager/lib/ea_maintenance_mode_manager/maintenance_mode", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/home/remi/.local/lib/python3.6/site-packages/importlib_metadata/__init__.py", line 105, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/remi/robot-artificial-intelligence/install/ea_maintenance_mode_manager/lib/python3.6/site-packages/ea_maintenance_mode_manager/maintenance_mode.py", line 22, in <module>
    from pynput import keyboard 
  File "/usr/local/lib/python3.6/dist-packages/pynput/__init__.py", line 40, in <module>
    from . import keyboard
  File "/usr/local/lib/python3.6/dist-packages/pynput/keyboard/__init__.py", line 52, in <module>
    from ._xorg import KeyCode, Key, Controller, Listener
  File "/usr/local/lib/python3.6/dist-packages/pynput/keyboard/_xorg.py", line 39, in <module>
    from pynput._util.xorg import (
  File "/usr/local/lib/python3.6/dist-packages/pynput/_util/xorg.py", line 40, in <module>
    _check()
  File "/usr/local/lib/python3.6/dist-packages/pynput/_util/xorg.py", line 38, in _check
    display = Xlib.display.Display()
  File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/protocol/display.py", line 84, in __init__
    name, protocol, host, displayno, screenno = connect.get_display(display)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/connect.py", line 73, in get_display
    return mod.get_display(display)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/support/unix_connect.py", line 76, in get_display
    raise error.DisplayNameError(display)
Xlib.error.DisplayNameError: Bad display name ""

I know that this error is because on Linux pynput uses X to control the keyboard and an environnement variable $DISPLAY is created. So I wanted to set it when running the script remotely (after being connected via ssh) :

DISPLAY=":0" python3 path_to_my_script/my-script.py

After running this line I get the following error :

Traceback (most recent call last):
  File "src/ea_maintenance_mode_manager/ea_maintenance_mode_manager/maintenance_mode.py", line 22, in <module>
    from pynput import keyboard 
  File "/usr/local/lib/python3.6/dist-packages/pynput/__init__.py", line 40, in <module>
    from . import keyboard
  File "/usr/local/lib/python3.6/dist-packages/pynput/keyboard/__init__.py", line 52, in <module>
    from ._xorg import KeyCode, Key, Controller, Listener
  File "/usr/local/lib/python3.6/dist-packages/pynput/keyboard/_xorg.py", line 39, in <module>
    from pynput._util.xorg import (
  File "/usr/local/lib/python3.6/dist-packages/pynput/_util/xorg.py", line 40, in <module>
    _check()
  File "/usr/local/lib/python3.6/dist-packages/pynput/_util/xorg.py", line 38, in _check
    display = Xlib.display.Display()
  File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/usr/local/lib/python3.6/dist-packages/Xlib/protocol/display.py", line 166, in __init__
    raise error.DisplayConnectionError(self.display_name, r.reason)
Xlib.error.DisplayConnectionError: Can't connect to display ":0": b'No protocol specified\n'

When I connect directly to the embedded computer and type in term :

echo $DISPLAY

I get :0

Is there a way to emulate a display via ssh to use the package pynput ?

Thank you

Rémi
  • 21
  • 2

2 Answers2

0

One workaround is to use sshkeyboard library instead of pynput as it does not require X server or DISPLAY value to be set. It has some same features as pynput such as reacting to the user input, but it cannot for example mock key presses.

ilon
  • 171
  • 1
  • 5
-1

I'm working on a similar problem. I gather pynput required a X server running and using Xvfb to start a virtual X server may resolve, but I do not have working yet.

shorton
  • 323
  • 3
  • 13
  • Perhaps it's not my place, but why are you answering if you don't really have an answer? – Scratte Oct 17 '20 at 16:53
  • It was a step I think he's missing from me trying to solve my own problem. Not a complete solution, but maybe enough for him. – shorton Oct 17 '20 at 17:09
  • 1
    Thank you for your answer, even thought I did not use it, I got around the problem by using an embedded display. So this question is still open. – Rémi Nov 20 '20 at 15:43
  • [This thread] (https://unix.stackexchange.com/questions/427345/keyboard-monitoring-without-display)might be helpful. My case is even if you can connect with X server without any error, the pynput listener still won't work. – L3w1s Aug 07 '23 at 01:29