pylspci - PCI Device Parser
pylspci is a Python library that provides a convenient interface to parse the output of the `lspci -mmnn` command, transforming it into Python objects. It can be used to query PCI devices on local or remote UNIX machines. The current version is 0.4.3, with an infrequent release cadence, though a 0.5.0 release candidate was published in January 2025.
Common errors
-
pcilib: Error reading /sys/bus/pci/devices/0000:00:08.3/label: Ope...
cause This error message originates from the underlying `lspci` utility, indicating it failed to read information from a specific PCI device path in `/sys/bus/pci/devices`. This can be due to insufficient permissions, hardware-specific quirks, or a device not responding correctly.fixEnsure the user running the `pylspci` script has root privileges or sufficient permissions to access `/sys/bus/pci/devices`. For local machines, try running with `sudo python your_script.py`. For remote, confirm the `username` and `password` provided to `ScannerPCI` have `sudo` access on the target. If the issue persists, it might be a hardware-specific anomaly that can often be safely ignored if no functional problems are observed. -
pylspci.exceptions.ConnectionException: Connection to 192.168.1.1 failed: Authentication failed.
cause The provided username or password for the remote connection is incorrect, or the user does not have `sudo` privileges on the target machine to execute `lspci`.fixVerify the `username` and `password` passed to `ScannerPCI` are correct for the target `ip`. Ensure the specified user has permissions to run `sudo lspci` without requiring additional password prompts on the remote host, or that the provided password correctly authenticates for `sudo` if needed.
Warnings
- gotcha The underlying `lspci` command requires `sudo` privileges for full functionality and especially for accessing detailed configuration space information. If `pylspci` is run without sufficient permissions, it may return incomplete data or fail to connect. For local scans, provide a password if the user is not root; for remote scans, ensure the user has `sudo` access.
- gotcha Using extremely verbose `lspci` options (like `lspci -xxx` for hexadecimal dump of configuration space) can, in rare cases, crash certain PCI devices, potentially leading to system instability or data loss. While `pylspci` primarily uses `lspci -mmnn`, direct interaction with `lspci` or future `pylspci` features that expose more verbose modes should be handled with caution.
Install
-
pip install pylspci
Imports
- ScannerPCI
from pylspci import ScannerPCI
Quickstart
import os
from pylspci import ScannerPCI
# Example for a remote connection, using environment variables for credentials
# For local scan, if current user can run lspci without sudo, password can be omitted.
# If local scan requires sudo, provide password or ensure user has sudo access without password.
# Replace with your target IP, username, and ensure PCI_PASSWORD is set in your environment
target_ip = os.environ.get('PCI_HOST_IP', '127.0.0.1')
username = os.environ.get('PCI_USERNAME', 'root')
password = os.environ.get('PCI_PASSWORD', '')
try:
# Connect to the target machine
# For local machine requiring sudo, you'd typically pass ip='127.0.0.1', password=password
# For remote, provide IP, username, and password.
if target_ip == '127.0.0.1' and not password: # Attempt local without password if not explicitly set
scanner = ScannerPCI(ip=target_ip)
elif target_ip == '127.0.0.1': # Local with password
scanner = ScannerPCI(ip=target_ip, password=password)
else: # Remote connection
scanner = ScannerPCI(ip=target_ip, username=username, password=password)
# Select all PCI devices
devices = scanner.select()
print(f"Found {len(devices)} PCI devices:")
for device in devices:
print(f" - {device.slot}: {device.vendor_name} {device.device_name} ({device.device_class_name})")
# Example: Find all network controllers
network_controllers = scanner.select(device_class_name='*Ethernet*')
if network_controllers:
print("\nNetwork Controllers:")
for nc in network_controllers:
print(f" - {nc.slot}: {nc.vendor_name} {nc.device_name}")
else:
print("\nNo network controllers found.")
except Exception as e:
print(f"An error occurred: {e}")