1

In order to access a a USB HID device connected on my computer I use the function find_all_hid_devices()from the pywinusb package.

Now I would like to access this HID device from an asyncio coroutine. With the following code

@asyncio.coroutine
def main():
    from pywinusb import hid
    a = hid.find_all_hid_devices()

The following error is returned:

Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\pywinusb\hid\core.py", line 122, in find_all_hid_devices
    for interface_data in winapi.enum_device_interfaces(h_info, guid):
  File "C:\Python34\lib\site-packages\pywinusb\hid\winapi.py", line 466, in enum_device_interfaces
    byref(dev_interface_data) ):
ctypes.ArgumentError: argument 1: <class 'OverflowError'>: int too long to convert

The same call to hid.find_all_hid_devices() however works on its own, in a plain main without asyncio.

Is this due to the fact that I'm trying to access within a coroutine? What is the proper way to achieve this?

Namux
  • 305
  • 5
  • 17

1 Answers1

1

pywinusb library is synchronous by design, thus you should call it in thread pool.

@asyncio.coroutine
def f():
    loop = asyncio.get_event_loop()
    a = yield from loop.run_in_executor(None, hid.find_all_hid_devices)

Synchronous call from coroutine is allowed technically but discouraged because it pauses event loop for long time period.

Andrew Svetlov
  • 16,730
  • 8
  • 66
  • 69
  • Awesome, thanks for your answer! Once I get my HID device, the code I must run on it is also (unfortunately) synchronous (e.g. `device.dosomething1`, `device.dosomething2`). Would you suggest, although discouraged, that I wrap all these instructions in a thread pool also? – Namux Aug 16 '15 at 14:49
  • To be clean: passing sync calls into thread pool is totally fine, the pool is intended to this usage. Pushing sync call into executor converts it into async call from asyncio perspective. So yes, please stay on this way. – Andrew Svetlov Aug 16 '15 at 15:19