moses-palmer / pynput

Sends virtual input commands
GNU Lesser General Public License v3.0
1.78k stars 247 forks source link

AttributeError: record_create_context #595

Open bryanhughes opened 6 months ago

bryanhughes commented 6 months ago

Description I am trying to use pynput and getting the exception AttributeError: record_create_context

Platform and pynput version

System is Ubuntu 22.04: Linux mimzy-jetson 5.15.122-tegra #1 SMP PREEMPT Mon Dec 18 21:24:25 PST 2023 aarch64 aarch64 aarch64 GNU/Linux
Version 1.7.6

To Reproduce Unfortunately my problem is a little more complex. I have a SoundRecorder class that has a threaded function that does the actual recording. Here is the main block of code. I don't understand this exception.

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG, format='%(message)s')
    parser = argparse.ArgumentParser()
    # Vision
    parser.add_argument(
        "-d", "--device_name",
        type=str,
        default=None,
        help='Audio device name. e.g. python3 -m sounddevice'
    )
    args = parser.parse_args()
    if args.device_name is None:
        dname = 'default'
    else:
        dname = args.device_name

    # start recorder thread
    recorder = SoundRecorder(dname)

    def on_press(key):
        if key == keyboard.Key.space:
            logging.info(f'[{_FILE.stem}] - Started recording - {key}')
            recorder.start()
        else:
            logging.info(f'[{_FILE.stem}] incorrect character {key}, press space')

    def on_release(key):
        logging.info(f'[{_FILE.stem}] {key} released')
        if key == keyboard.Key.space:
            logging.info(f'[{_FILE.stem}] {key} stop')
            recorder.stop()
            return False

    while True:
        # monitor keyboard
        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

        if not recorder.is_recording():
            logging.info(f"[{_FILE.stem}] READY")

The full stack trace

[mimzy_lam] Recording device: <Microphone PowerConf S3 Mono (1 channels)>
Traceback (most recent call last):
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/Xlib/display.py", line 224, in __getattr__
    function = self.display_extension_methods[attr]
KeyError: 'record_create_context'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/pynput/_util/__init__.py", line 411, in receive
    yield
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/pynput/keyboard/_xorg.py", line 545, in _run
    super(Listener, self)._run()
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/pynput/_util/xorg.py", line 386, in _run
    self._context = dm.record_create_context(
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/Xlib/display.py", line 227, in __getattr__
    raise AttributeError(attr)
AttributeError: record_create_context
python-BaseException
Exception in thread Thread-6:
Traceback (most recent call last):
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/Xlib/display.py", line 224, in __getattr__
    function = self.display_extension_methods[attr]
KeyError: 'record_create_context'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/pynput/_util/__init__.py", line 210, in run
    self._run()
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/pynput/keyboard/_xorg.py", line 545, in _run
    super(Listener, self)._run()
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/pynput/_util/xorg.py", line 386, in _run
    self._context = dm.record_create_context(
  File "/home/bryan/.cache/pypoetry/virtualenvs/mimzy-8gc2sb4S-py3.10/lib/python3.10/site-packages/Xlib/display.py", line 227, in __getattr__
    raise AttributeError(attr)
AttributeError: record_create_context
bryanhughes commented 6 months ago

This appears to be happening because I am using the machine remotely and accessing via ssh -X ...

moses-palmer commented 5 months ago

Thank you for your report.

I notice that your Xlib bindings appear to come from site-packages/Xlib whereas the declared dependencies for this library include python_xlib. Could this be the reason for the unexpected error when running over SSH? Then again, this X extension is hopefully not exposed over SSH anyway.

rafaelBauer commented 4 months ago

I ran into the same problem. I am running over SSH like ssh -X ..., and I also noticed that my Xlib bindings are coming from site-packages/Xlib.

But I just realized that the library module of python-xlib is actually Xlib - like the folder name is actually Xlib (see in the python-xlib repo) so that seems to be correct... I am not sure how to proceed from here... Any hints?

rafaelBauer commented 4 months ago

It seems that that attribute is present only when the RECORD extension is loaded by the XServer. The method record_create_context is appended to the display object at Xlib/ext/record.py. I saw that for me this extension is not "loaded" or not there. To print it, I ran xdpyinfo -display :10 -queryExtensions. My list of extensions are:

number of extensions:    22
    Apple-DRI  (opcode: 129, base event: 64, base error: 128)
    Apple-WM  (opcode: 130, base event: 68, base error: 130)
    BIG-REQUESTS  (opcode: 135)
    DAMAGE  (opcode: 143, base event: 98, base error: 156)
    DOUBLE-BUFFER  (opcode: 145, base error: 157)
    GLX  (opcode: 149, base event: 102, base error: 161)
    Generic Event Extension  (opcode: 131)
    MIT-SCREEN-SAVER  (opcode: 144, base event: 99)
    MIT-SHM  (opcode: 133, base event: 72, base error: 132)
    Present  (opcode: 146)
    RANDR  (opcode: 142, base event: 96, base error: 151)
    RENDER  (opcode: 141, base error: 146)
    SECURITY  (opcode: 139, base event: 93, base error: 142)
    SHAPE  (opcode: 132, base event: 71)
    SYNC  (opcode: 136, base event: 90, base error: 138)
    X-Resource  (opcode: 147)
    XC-MISC  (opcode: 138)
    XFIXES  (opcode: 140, base event: 94, base error: 144)
    XINERAMA  (opcode: 128)
    XInputExtension  (opcode: 134, base event: 73, base error: 133)
    XKEYBOARD  (opcode: 137, base event: 92, base error: 141)
    XVideo  (opcode: 148, base event: 100, base error: 158)

I am still looking at it to see how to enable that. If you know how to do it, I'd be glad to hear, so I can test it. I was wondering if we really need to rely on the record extension to make pynput work. Could we rely only oin the XKeyboard and XInputExtension?

rafaelBauer commented 4 months ago

Any follow-up on this?

meghbhalerao commented 2 days ago

Any resolution to this issue? I am using the robosuite package - https://robosuite.ai - and want to control the simulation robot. My images are rendered thru the ssh connection when I log in using -XY flags, but when I used my keyboard to move the sim robot it does not work in an ssh session. However, it works when I go to the physical machine and try it out. Detailed error is below -

Traceback (most recent call last):
  File "/home/megh/projects/venv_envs/mimicgen/lib/python3.8/site-packages/Xlib/display.py", line 224, in __getattr__
    function = self.display_extension_methods[attr]
KeyError: 'record_create_context'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/home/megh/projects/venv_envs/mimicgen/lib/python3.8/site-packages/pynput/_util/__init__.py", line 211, in run
    self._run()
  File "/home/megh/projects/venv_envs/mimicgen/lib/python3.8/site-packages/pynput/keyboard/_xorg.py", line 559, in _run
    super(Listener, self)._run()
  File "/home/megh/projects/venv_envs/mimicgen/lib/python3.8/site-packages/pynput/_util/xorg.py", line 386, in _run
    self._context = dm.record_create_context(
  File "/home/megh/projects/venv_envs/mimicgen/lib/python3.8/site-packages/Xlib/display.py", line 227, in __getattr__
    raise AttributeError(attr)
AttributeError: record_create_context