title: Is it possible to obtain USB device node (file) with Python (PyUSB)?
body: <p>I am trying to find a way to iterate over all USB devices on a Raspberry Pi, and print out Vendor ID, Product ID, manufacturer name, and device node; via posts like:</p>
  <ul>
  <li><a href="https://stackoverflow.com/questions/8110310/simple-way-to-query-connected-usb-devices-info-in-python">Simple way to query connected USB devices info in Python?</a></li>
  <li><a href="https://stackoverflow.com/questions/9577601/detect-the-state-of-a-switch-connected-to-usb-with-python">Detect the state of a switch connected to USB with python</a></li>
  <li><a href="https://stackoverflow.com/questions/18224189/get-usb-device-address-through-python">Get USB device address through python</a></li>
  </ul>
  <p>... I understood I could use PyUSB - but I'm having lots of trouble, similar to:</p>
  <ul>
  <li><a href="https://stackoverflow.com/questions/38570959/pyusb-why-are-bus-dirname-and-dev-filename-empty-string">PyUSB: Why are bus.dirname and dev.filename empty string?</a></li>
  </ul>
  <p>... which that post does not answer.</p>
  <p>So here is my test case - I have this on the Raspberry Pi Raspbian Stretch:</p>
  <pre class="lang-none prettyprint-override"><code>pi@raspberry:~ $ apt-show-versions -r libusb
  libusb-0.1-4:armhf/stretch 2:0.1.12-30 uptodate
  libusb-1.0-0:armhf/stretch 2:1.0.21-1 uptodate
  libusbmuxd4:armhf/stretch 1.0.10-3 uptodate
  </code></pre>
  <p>I installed PyUSB with:</p>
  <pre><code>sudo pip3 install pyusb
  </code></pre>
  <p>As an example, I've connected an Arduino UNO to the Raspberry Pi; <code>tail -f /var/log/syslog</code> prints this upon USB connection:</p>
  <pre class="lang-none prettyprint-override"><code>...
  Jun 23 09:35:01 raspberry kernel: [71431.582554] usb 1-1.2: new full-speed USB device number 7 using dwc_otg
  Jun 23 09:35:01 raspberry kernel: [71431.726403] usb 1-1.2: New USB device found, idVendor=2341, idProduct=0043, bcdDevice= 0.01
  Jun 23 09:35:01 raspberry kernel: [71431.726420] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
  Jun 23 09:35:01 raspberry kernel: [71431.726431] usb 1-1.2: Manufacturer: Arduino (www.arduino.cc)
  Jun 23 09:35:01 raspberry kernel: [71431.726440] usb 1-1.2: SerialNumber: 64131383231351C03272
  Jun 23 09:35:01 raspberry mtp-probe: checking bus 1, device 7: &quot;/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2&quot;
  Jun 23 09:35:01 raspberry mtp-probe: bus: 1, device: 7 was not an MTP device
  Jun 23 09:35:01 raspberry kernel: [71431.778630] cdc_acm 1-1.2:1.0: ttyACM0: USB ACM device
  Jun 23 09:35:01 raspberry kernel: [71431.779553] usbcore: registered new interface driver cdc_acm
  Jun 23 09:35:01 raspberry kernel: [71431.779562] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
  ...
  </code></pre>
  <p>So, I know that Vendor ID is 0x2341 (apparently, hex), Product ID is 0x0043 (apparently, hex), manufacturer name is <code>Arduino (www.arduino.cc)</code>, and device node/file is <code>/dev/ttyACM0</code>; and I simply want to print this out for all USB devices that are connected to the system via PyUSB.</p>
  <p>Now, there is a bit of confusion online, since apparently, you can iterate over USB devices in PyUSB in two ways: the old &quot;legacy&quot; way, and the &quot;new&quot; way/API. So, I made a test script which tries them both, which I call <code>test-usb.py</code>:</p>
  <pre class="lang-python prettyprint-override"><code>#!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  
  import usb.core
  import usb.util
  
  print(&quot;This is 'old' PyUSB style iteration - uses legacy:&quot;)
  busses = usb.busses()  # SO:8110310
  for bus in busses:
    print(type(bus)) # &lt;class 'usb.legacy.Bus'&gt;
    devices = bus.devices
    for dev in devices:
      if dev != None:
        try:
          xdev = usb.core.find(idVendor=dev.idVendor, idProduct=dev.idProduct)
          if xdev._manufacturer is None:
            xdev._manufacturer = usb.util.get_string(xdev, xdev.iManufacturer)
          if xdev._product is None:
            xdev._product = usb.util.get_string(xdev, xdev.iProduct)
          stx = &quot;USB VID: 0x{:04X} PID: 0x{:04X} Mfr name '{}' Product '{}'&quot;.format(dev.idVendor, dev.idProduct, str(xdev._manufacturer).strip(), str(xdev._product).strip(), dev.filename)
          print( stx )
          try:
            print(&quot;xdev.filename: '{}'&quot;.format(xdev.filename))
          except Exception as e:
            print(&quot;xdev.filename exception: {}&quot;.format(e))
          try:
            print(&quot;dev.filename: '{}'&quot;.format(dev.filename))
          except Exception as e:
            print(&quot;dev.filename exception: {}&quot;.format(e))
        except Exception as e:
          print(&quot;Exception: {}&quot;.format(e))
  
  print()
  
  def print_internals(dev): # SO: 18224189
    for attrib in dir(dev):
      if not attrib.startswith('_') and not attrib == 'configurations':
        try:
          x=getattr(dev, attrib)
          print( &quot;  &quot;, attrib, x)
        except Exception as e:
          print(&quot;Exception for attrib '{}': {}&quot;.format(attrib, e))
    try:
      for config in dev.configurations:
        for attrib in dir(config):
          if not attrib.startswith('_'):
            try:
              x=getattr(config, attrib)
              print( &quot;  &quot;, attrib, x)
            except Exception as e:
              print(&quot;Exception for attrib '{}': {}&quot;.format(attrib, e))
    except Exception as e:
      print(&quot;Exception config in dev.configurations: {}&quot;.format(e))
  
  print(&quot;This is 'new' PyUSB style iteration - does not use legacy:&quot;)
  for xdev in usb.core.find(find_all=True): # SO:9577601
    print(type(xdev)) # &lt;class 'usb.core.Device'&gt;
    try:
      if xdev._manufacturer is None:
        xdev._manufacturer = usb.util.get_string(xdev, xdev.iManufacturer)
    except Exception as e:
      print(&quot;Exception: {}&quot;.format(e))
    try:
      if xdev._product is None:
        xdev._product = usb.util.get_string(xdev, xdev.iProduct)
    except Exception as e:
      print(&quot;Exception: {}&quot;.format(e))
    stx = &quot;USB VID: 0x{:04X} PID: 0x{:04X} Mfr name '{}' Product '{}'&quot;.format(xdev.idVendor, xdev.idProduct, str(xdev._manufacturer).strip(), str(xdev._product).strip())
    print( stx )
    try:
      print(&quot;xdev.filename: '{}'&quot;.format(xdev.filename))
    except Exception as e:
      print(&quot;xdev.filename exception: {}&quot;.format(e))
    print_internals(xdev)
  </code></pre>
  <p>The above script outputs:</p>
  <pre class="lang-none prettyprint-override"><code>pi@raspberry:~ $ python3 test-usb.py
  This is 'old' PyUSB style iteration - uses legacy:
  &lt;class 'usb.legacy.Bus'&gt;
  Exception: The device has no langid
  USB VID: 0x0424 PID: 0x7800 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
  dev.filename: ''
  USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
  dev.filename: ''
  USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
  dev.filename: ''
  Exception: The device has no langid
  
  This is 'new' PyUSB style iteration - does not use legacy:
  &lt;class 'usb.core.Device'&gt;
  Exception: The device has no langid
  Exception: The device has no langid
  USB VID: 0x2341 PID: 0x0043 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
     address 7
     attach_kernel_driver &lt;bound method Device.attach_kernel_driver of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     bDescriptorType 1
     bDeviceClass 2
     bDeviceProtocol 0
     bDeviceSubClass 0
     bLength 18
     bMaxPacketSize0 8
     bNumConfigurations 1
     backend &lt;usb.backend.libusb1._LibUSB object at 0x7680f510&gt;
     bcdDevice 1
     bcdUSB 272
     bus 1
     clear_halt &lt;bound method Device.clear_halt of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     ctrl_transfer &lt;bound method Device.ctrl_transfer of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     default_timeout 1000
     detach_kernel_driver &lt;bound method Device.detach_kernel_driver of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     finalize &lt;bound method AutoFinalizedObject.finalize of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     get_active_configuration &lt;bound method Device.get_active_configuration of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     iManufacturer 1
     iProduct 2
     iSerialNumber 220
     idProduct 67
     idVendor 9025
     is_kernel_driver_active &lt;bound method Device.is_kernel_driver_active of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     langids ()
  Exception for attrib 'manufacturer': The device has no langid
     port_number 2
     port_numbers (1, 2)
  Exception for attrib 'product': The device has no langid
     read &lt;bound method Device.read of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     reset &lt;bound method Device.reset of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
  Exception for attrib 'serial_number': The device has no langid
     set_configuration &lt;bound method Device.set_configuration of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     set_interface_altsetting &lt;bound method Device.set_interface_altsetting of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
     speed 2
     write &lt;bound method Device.write of &lt;DEVICE ID 2341:0043 on Bus 001 Address 007&gt;&gt;
  Exception config in dev.configurations: 'method' object is not iterable
  &lt;class 'usb.core.Device'&gt;
  USB VID: 0x0424 PID: 0x7800 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
     address 4
     attach_kernel_driver &lt;bound method Device.attach_kernel_driver of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     bDescriptorType 1
     bDeviceClass 255
     bDeviceProtocol 255
     bDeviceSubClass 0
     bLength 18
     bMaxPacketSize0 64
     bNumConfigurations 1
     backend &lt;usb.backend.libusb1._LibUSB object at 0x7680f510&gt;
     bcdDevice 768
     bcdUSB 528
     bus 1
     clear_halt &lt;bound method Device.clear_halt of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     ctrl_transfer &lt;bound method Device.ctrl_transfer of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     default_timeout 1000
     detach_kernel_driver &lt;bound method Device.detach_kernel_driver of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     finalize &lt;bound method AutoFinalizedObject.finalize of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     get_active_configuration &lt;bound method Device.get_active_configuration of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     iManufacturer 0
     iProduct 0
     iSerialNumber 0
     idProduct 30720
     idVendor 1060
     is_kernel_driver_active &lt;bound method Device.is_kernel_driver_active of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     langids ()
     manufacturer None
     port_number 1
     port_numbers (1, 1, 1)
     product None
     read &lt;bound method Device.read of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     reset &lt;bound method Device.reset of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     serial_number None
     set_configuration &lt;bound method Device.set_configuration of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     set_interface_altsetting &lt;bound method Device.set_interface_altsetting of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
     speed 3
     write &lt;bound method Device.write of &lt;DEVICE ID 0424:7800 on Bus 001 Address 004&gt;&gt;
  Exception config in dev.configurations: 'method' object is not iterable
  &lt;class 'usb.core.Device'&gt;
  USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
     address 3
     attach_kernel_driver &lt;bound method Device.attach_kernel_driver of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     bDescriptorType 1
     bDeviceClass 9
     bDeviceProtocol 2
     bDeviceSubClass 0
     bLength 18
     bMaxPacketSize0 64
     bNumConfigurations 1
     backend &lt;usb.backend.libusb1._LibUSB object at 0x7680f510&gt;
     bcdDevice 2995
     bcdUSB 512
     bus 1
     clear_halt &lt;bound method Device.clear_halt of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     ctrl_transfer &lt;bound method Device.ctrl_transfer of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     default_timeout 1000
     detach_kernel_driver &lt;bound method Device.detach_kernel_driver of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     finalize &lt;bound method AutoFinalizedObject.finalize of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     get_active_configuration &lt;bound method Device.get_active_configuration of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     iManufacturer 0
     iProduct 0
     iSerialNumber 0
     idProduct 9492
     idVendor 1060
     is_kernel_driver_active &lt;bound method Device.is_kernel_driver_active of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     langids ()
     manufacturer None
     port_number 1
     port_numbers (1, 1)
     product None
     read &lt;bound method Device.read of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     reset &lt;bound method Device.reset of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     serial_number None
     set_configuration &lt;bound method Device.set_configuration of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     set_interface_altsetting &lt;bound method Device.set_interface_altsetting of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
     speed 3
     write &lt;bound method Device.write of &lt;DEVICE ID 0424:2514 on Bus 001 Address 003&gt;&gt;
  Exception config in dev.configurations: 'method' object is not iterable
  &lt;class 'usb.core.Device'&gt;
  USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
     address 2
     attach_kernel_driver &lt;bound method Device.attach_kernel_driver of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     bDescriptorType 1
     bDeviceClass 9
     bDeviceProtocol 2
     bDeviceSubClass 0
     bLength 18
     bMaxPacketSize0 64
     bNumConfigurations 1
     backend &lt;usb.backend.libusb1._LibUSB object at 0x7680f510&gt;
     bcdDevice 2995
     bcdUSB 512
     bus 1
     clear_halt &lt;bound method Device.clear_halt of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     ctrl_transfer &lt;bound method Device.ctrl_transfer of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     default_timeout 1000
     detach_kernel_driver &lt;bound method Device.detach_kernel_driver of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     finalize &lt;bound method AutoFinalizedObject.finalize of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     get_active_configuration &lt;bound method Device.get_active_configuration of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     iManufacturer 0
     iProduct 0
     iSerialNumber 0
     idProduct 9492
     idVendor 1060
     is_kernel_driver_active &lt;bound method Device.is_kernel_driver_active of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     langids ()
     manufacturer None
     port_number 1
     port_numbers (1,)
     product None
     read &lt;bound method Device.read of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     reset &lt;bound method Device.reset of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     serial_number None
     set_configuration &lt;bound method Device.set_configuration of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     set_interface_altsetting &lt;bound method Device.set_interface_altsetting of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
     speed 3
     write &lt;bound method Device.write of &lt;DEVICE ID 0424:2514 on Bus 001 Address 002&gt;&gt;
  Exception config in dev.configurations: 'method' object is not iterable
  &lt;class 'usb.core.Device'&gt;
  Exception: The device has no langid
  Exception: The device has no langid
  USB VID: 0x1D6B PID: 0x0002 Mfr name 'None' Product 'None'
  xdev.filename exception: 'Device' object has no attribute 'filename'
     address 1
     attach_kernel_driver &lt;bound method Device.attach_kernel_driver of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     bDescriptorType 1
     bDeviceClass 9
     bDeviceProtocol 1
     bDeviceSubClass 0
     bLength 18
     bMaxPacketSize0 64
     bNumConfigurations 1
     backend &lt;usb.backend.libusb1._LibUSB object at 0x7680f510&gt;
     bcdDevice 1049
     bcdUSB 512
     bus 1
     clear_halt &lt;bound method Device.clear_halt of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     ctrl_transfer &lt;bound method Device.ctrl_transfer of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     default_timeout 1000
     detach_kernel_driver &lt;bound method Device.detach_kernel_driver of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     finalize &lt;bound method AutoFinalizedObject.finalize of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     get_active_configuration &lt;bound method Device.get_active_configuration of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     iManufacturer 3
     iProduct 2
     iSerialNumber 1
     idProduct 2
     idVendor 7531
     is_kernel_driver_active &lt;bound method Device.is_kernel_driver_active of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     langids ()
  Exception for attrib 'manufacturer': The device has no langid
     port_number 0
     port_numbers None
  Exception for attrib 'product': The device has no langid
     read &lt;bound method Device.read of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     reset &lt;bound method Device.reset of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
  Exception for attrib 'serial_number': The device has no langid
     set_configuration &lt;bound method Device.set_configuration of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     set_interface_altsetting &lt;bound method Device.set_interface_altsetting of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
     speed 3
     write &lt;bound method Device.write of &lt;DEVICE ID 1d6b:0002 on Bus 001 Address 001&gt;&gt;
  Exception config in dev.configurations: 'method' object is not iterable
  </code></pre>
  <p>So, the only thing I could get to, is USB VID: 0x2341 PID: 0x0043; the exception <code>The device has no langid</code> prevents retrieval of manufacturer and product name (and there are a ton of other exceptions, too)</p>
  <p>And no one knows where the device node/path is: apparently, there used to be a <code>dev.filename</code> in the &quot;legacy&quot; mode, which maybe at a certain point in the past, maybe did contain the device node/file <code>/dev/ttyACM0</code> - but now seemingly does not anymore, as it is empty; and I couldn't find a mention of where that information resides in the &quot;new&quot; API (if it's there).</p>
  <p>So - how can I iterate over all USB devices in Python 3 in Linux, and print out Vendor ID, Product ID, manufacturer name, and device node filename? If this is not possible with PyUSB - what other options do I have in terms of Python libraries (I'd like to avoid parsing <code>/var/log/syslog</code> or <code>/dev/bus</code> manually)?</p>