pyudev - libudev binding

A binding to libudev.

A Context object is required for almost any functionality in pyudev. The context provides Device enumeration with Context.list_devices().

Device monitoring is provided by Monitor and MonitorObserver. With pyudev.pyqt4, pyudev.pyside, pyudev.glib and pyudev.wx device monitoring can be integrated into the event loop of various GUI toolkits.

pyudev.__version__

The version of pyudev as string. This string contains a major and a minor version number, and optionally a revision in the form major.minor.revision. As said, the revision part is optional and may not be present.

This attribute is mainly intended for display purposes, use __version_info__ to check the version of pyudev in source code.

pyudev.__version_info__

The version of pyudev as tuple of integers. This tuple contains a major and a minor number, and optionally a revision number in the form (major, minor, revision). As said, the revision component is optional and may not be present.

New in version 0.10.

pyudev.udev_version()

Get the version of the underlying udev library.

udev doesn’t use a standard major-minor versioning scheme, but instead labels releases with a single consecutive number. Consequently, the version number returned by this function is a single integer, and not a tuple (like for instance the interpreter version in sys.version_info).

As libudev itself does not provide a function to query the version number, this function calls the udevadm utilitiy, so be prepared to catch EnvironmentError and CalledProcessError if you call this function.

Return the version number as single integer. Raise ValueError, if the version number retrieved from udev could not be converted to an integer. Raise EnvironmentError, if udevadm was not found, or could not be executed. Raise subprocess.CalledProcessError, if udevadm returned a non-zero exit code. On Python 2.7 or newer, the output attribute of this exception is correctly set.

New in version 0.8.

Context – UDev database context

class pyudev.Context

The udev context.

This is the central object to access udev. An instance of this class must be created before anything else can be done. It holds the udev configuration and provides the interface to list devices (see list_devices()).

Instances of this class can directly be given as udev * to functions wrapped through ctypes.

__init__()

Create a new context.

sys_path

The sysfs mount point defaulting to /sys' as unicode string.

The mount point can be overwritten using the environment variable SYSFS_PATH. Use this for testing purposes.

device_path

The device directory path defaulting to /dev as unicode string.

This can be overridden in the udev configuration.

run_path

The run runtime directory path defaulting to /run as unicode string.

Required udev version: 167

New in version 0.10.

log_priority

The logging priority of the interal logging facitility of udev as integer with a standard syslog priority. Assign to this property to change the logging priority.

UDev uses the standard syslog priorities. Constants for these priorities are defined in the syslog module in the standard library:

>>> import syslog
>>> context = pyudev.Context()
>>> context.log_priority = syslog.LOG_DEBUG

New in version 0.9.

list_devices(**kwargs)

List all available devices.

The arguments of this method are the same as for Enumerator.match(). In fact, the arguments are simply passed straight to method match().

This function creates and returns an Enumerator object, that can be used to filter the list of devices, and eventually retrieve Device objects representing matching devices.

Changed in version 0.8: Accept keyword arguments now for easy matching

Enumerator – device enumeration and filtering

class pyudev.Enumerator

Enumerate all available devices.

To retrieve devices, simply iterate over an instance of this class. This operation yields Device objects representing the available devices.

Before iteration the device list can be filtered by subsystem or by property values using match_subsystem() and match_property(). Multiple subsystem (property) filters are combined using a logical OR, filters of different types are combined using a logical AND. The following filter for instance:

devices.match_subsystem('block').match_property(
    'ID_TYPE', 'disk').match_property('DEVTYPE', 'disk')

means the following:

subsystem == 'block' and (ID_TYPE == 'disk' or DEVTYPE == 'disk')

Once added, a filter cannot be removed anymore. Create a new object instead.

Instances of this class can directly be given as given udev_enumerate * to functions wrapped through ctypes.

match(**kwargs)

Include devices according to the rules defined by the keyword arguments. These keyword arguments are interpreted as follows:

  • The value for the keyword argument subsystem is forwarded to match_subsystem().
  • The value for the keyword argument sys_name is forwared to match_sys_name().
  • The value for the keyword argument tag is forwared to match_tag().
  • The value for the keyword argument parent is forwared to match_parent().
  • All other keyword arguments are forwareded one by one to match_property(). The keyword argument itself is interpreted as property name, the value of the keyword argument as the property value.

All keyword arguments are optional, calling this method without no arguments at all is simply a noop.

Return the instance again.

New in version 0.8.

Changed in version 0.13: Added parent keyword

match_subsystem(subsystem, nomatch=False)

Include all devices, which are part of the given subsystem.

subsystem is either a unicode string or a byte string, containing the name of the subsystem. If nomatch is True (default is False), the match is inverted: A device is only included if it is not part of the given subsystem.

Return the instance again.

match_sys_name(sys_name)

Include all devices with the given name.

sys_name is a byte or unicode string containing the device name.

Return the instance again.

New in version 0.8.

match_property(property, value)

Include all devices, whose property has the given value.

property is either a unicode string or a byte string, containing the name of the property to match. value is a property value, being one of the following types:

  • int()
  • bool()
  • A byte string
  • Anything convertable to a unicode string (including a unicode string itself)

Return the instance again.

match_attribute(attribute, value, nomatch=False)

Include all devices, whose attribute has the given value.

attribute is either a unicode string or a byte string, containing the name of a sys attribute to match. value is an attribute value, being one of the following types:

  • int(),
  • bool()
  • A byte string
  • Anything convertable to a unicode string (including a unicode string itself)

If nomatch is True (default is False), the match is inverted: A device is include if the attribute does not match the given value.

Note

If nomatch is True, devices which do not have the given attribute at all are also included. In other words, with nomatch=True the given attribute is not guaranteed to exist on all returned devices.

Return the instance again.

match_tag(tag)

Include all devices, which have the given tag attached.

tag is a byte or unicode string containing the tag name.

Return the instance again.

Required udev version: 154

New in version 0.6.

match_parent(parent)

Include all devices on the subtree of the given parent device.

The parent device itself is also included.

parent is a Device.

Return the instance again.

Required udev version: 172

New in version 0.13.

match_is_initialized()

Include only devices, which are initialized.

Initialized devices have properly set device node permissions and context, and are (in case of network devices) fully renamed.

Currently this will not affect devices which do not have device nodes and are not network interfaces.

Return the instance again.

Required udev version: 165

New in version 0.8.

__iter__()

Iterate over all matching devices.

Yield Device objects.

Device – accessing device information

class pyudev.Device

A single device with attached attributes and properties.

This class subclasses the Mapping ABC, providing a read-only dictionary mapping property names to the corresponding values. Therefore all well-known dicitionary methods and operators (e.g. .keys(), .items(), in) are available to access device properties.

Aside of the properties, a device also has a set of udev-specific attributes like the path inside sysfs.

Device objects compare equal and unequal to other devices and to strings (based on device_path). However, there is no ordering on Device objects, and the corresponding operators >, <, <= and >= raise TypeError.

Warning

Do never use object identity (is operator) to compare Device objects. pyudev may create multiple Device objects for the same device. Instead simply compare devices by value using == or !=.

Device objects are hashable and can therefore be used as keys in dictionaries and sets.

They can also be given directly as udev_device * to functions wrapped through ctypes.

Construction of device objects

classmethod from_path(context, path)

Create a device from a device path. The path may or may not start with the sysfs mount point:

>>> context = pyudev.Context()
>>> Device.from_path(context, '/devices/platform')
Device(u'/sys/devices/platform')
>>> Device.from_path(context, '/sys/devices/platform')
Device(u'/sys/devices/platform')

context is the Context in which to search the device. path is a device path as unicode or byte string.

Return a Device object for the device. Raise DeviceNotFoundAtPathError, if no device was found for path.

New in version 0.4.

classmethod from_sys_path(context, sys_path)

Create a new device from a given sys_path:

>>> context = pyudev.Context()
>>> Device.from_path(context, '/sys/devices/platform')
Device(u'/sys/devices/platform')

context is the Context in which to search the device. sys_path is a unicode or byte string containing the path of the device inside sysfs with the mount point included.

Return a Device object for the device. Raise DeviceNotFoundAtPathError, if no device was found for sys_path.

Changed in version 0.4: Raise NoSuchDeviceError instead of returning None, if no device was found for sys_path

Changed in version 0.5: Raise DeviceNotFoundAtPathError instead of NoSuchDeviceError

classmethod from_name(context, subsystem, sys_name)

Create a new device from a given subsystem and a given sys_name:

>>> context = pyudev.Context()
>>> sda = pyudev.Device.from_name(context, 'block', 'sda')
>>> sda
Device(u'/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda')
>>> sda == pyudev.Device.from_path(context, '/block/sda')

context is the Context in which to search the device. subsystem and sys_name are byte or unicode strings, which denote the subsystem and the name of the device to create.

Return a Device object for the device. Raise DeviceNotFoundByNameError, if no device was found with the given name.

New in version 0.5.

classmethod from_device_number(context, type, number)

Create a new device from a device number with the given device type:

>>> import os
>>> ctx = Context()
>>> major, minor = 8, 0
>>> device = Device.from_device_number(context, 'block',
...     os.makedev(major, minor))
>>> device
Device(u'/sys/devices/pci0000:00/0000:00:11.0/host0/target0:0:0/0:0:0:0/block/sda')
>>> os.major(device.device_number), os.minor(device.device_number)
(8, 0)

Use os.makedev() to construct a device number from a major and a minor device number, as shown in the example above.

Note

Device numbers are not unique across different device types. Passing a correct number with a wrong type may silently yield a wrong device object, so make sure to pass the correct device type.

context is the Context, in which to search the device. type is either 'char' or 'block', according to whether the device is a character or block device. number is the device number as integer.

Return a Device object for the device with the given device number. Raise DeviceNotFoundByNumberError, if no device was found with the given device type and number. Raise ValueError, if type is any other string than 'char' or 'block'.

New in version 0.11.

classmethod from_device_file(context, filename)

Create a new device from the given device file:

>>> context = Context()
>>> device = Device.from_device_file(context, '/dev/sda')
>>> device
Device(u'/sys/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0/block/sda')
>>> device.device_node
u'/dev/sda'

Warning

Though the example seems to suggest that device.device_node == filename holds with device = Device.from_device_file(context, filename), this is only true in a majority of cases. There can be devices, for which this relation is actually false! Thus, do not expect device_node to be equal to the given filename for the returned Device. Especially, use device_node if you need the device file of a Device created with this method afterwards.

context is the Context in which to search the device. filename is a string containing the path of a device file.

Return a Device representing the given device file. Raise ValueError if filename is no device file at all. Raise EnvironmentError if filename does not exist or if its metadata was inaccessible.

New in version 0.15.

classmethod from_environment(context)

Create a new device from the process environment (as in os.environ).

This only works reliable, if the current process is called from an udev rule, and is usually used for tools executed from IMPORT= rules. Use this method to create device objects in Python scripts called from udev rules.

context is the library Context.

Return a Device object constructed from the environment. Raise DeviceNotFoundInEnvironmentError, if no device could be created from the environment.

Required udev version: 152

New in version 0.6.

General attributes

context

The Context to which this device is bound.

New in version 0.5.

sys_path

Absolute path of this device in sysfs including the sysfs mount point as unicode string.

sys_name

Device file name inside sysfs as unicode string.

sys_number

The trailing number of the sys_name as unicode string, or None, if the device has no trailing number in its name.

Note

The number is returned as unicode string to preserve the exact format of the number, especially any leading zeros:

>>> device = pyudev.Device.from_path(ctx, '/sys/devices/LNXSYSTM:00')
>>> device.sys_number
u'00'

To work with numbers, explicitly convert them to ints:

>>> int(device.sys_number)
0

New in version 0.11.

device_path

Kernel device path as unicode string. This path uniquely identifies a single device.

Unlike sys_path, this path does not contain the sysfs mount point. However, the path is absolute and starts with a slash '/'.

tags

A Tags object representing the tags attached to this device.

The Tags object supports a test for a single tag as well as iteration over all tags:

>>> 'systemd' in device.tags
True
>>> list(device.tags)
[u'systemd', u'seat']

Tags are arbitrary classifiers that can be attached to devices by udev scripts and daemons. For instance, systemd uses tags for multi-seat support.

Required udev version: 154

New in version 0.6.

Changed in version 0.13: Return a Tags object now.

Device driver and subsystem

subsystem

Name of the subsystem this device is part of as unicode string.

driver

The driver name as unicode string, or None, if there is no driver for this device.

New in version 0.5.

device_type

Device type as unicode string, or None, if the device type is unknown.

>>> context = Context()
>>> for device in context.list_devices(subsystem='net'):
...     '{0} - {1}'.format(device.sys_name, device.device_type or 'ethernet')
...
u'eth0 - ethernet'
u'wlan0 - wlan'
u'lo - ethernet'
u'vboxnet0 - ethernet'

New in version 0.10.

Device nodes

device_node

Absolute path to the device node of this device as unicode string or None, if this device doesn’t have a device node. The path includes the device directory (see Context.device_path).

This path always points to the actual device node associated with this device, and never to any symbolic links to this device node. See device_links to get a list of symbolic links to this device node.

Warning

For devices created with from_device_file(), the value of this property is not necessary equal to the filename given to from_device_file().

device_number

The device number of the associated device as integer, or 0, if no device number is associated.

Use os.major() and os.minor() to decompose the device number into its major and minor number:

>>> context = Context()
>>> sda = Device.from_name(context, 'block', 'sda')
>>> sda.device_number
2048L
>>> (os.major(sda.device_number), os.minor(sda.device_number))
(8, 0)

For devices with an associated device_node, this is the same as the st_rdev field of the stat result of the device_node:

>>> os.stat(sda.device_node).st_rdev
2048

New in version 0.11.

An iterator, which yields the absolute paths (including the device directory, see Context.device_path) of all symbolic links pointing to the device_node of this device. The paths are unicode strings.

UDev can create symlinks to the original device node (see device_node) inside the device directory. This is often used to assign a constant, fixed device node to devices like removeable media, which technically do not have a constant device node, or to map a single device into multiple device hierarchies. The property provides access to all such symbolic links, which were created by UDev for this device.

Device initialization time

is_initialized

True, if the device is initialized, False otherwise.

A device is initialized, if udev has already handled this device and has set up device node permissions and context, or renamed a network device.

Consequently, this property is only implemented for devices with a device node or for network devices. On all other devices this property is always True.

It is not recommended, that you use uninitialized devices.

Required udev version: 165

New in version 0.8.

time_since_initialized

The time elapsed since initialization as timedelta.

This property is only implemented on devices, which need to store properties in the udev database. On all other devices this property is simply zero timedelta.

See also

is_initialized

Required udev version: 165

New in version 0.8.

Device hierarchy

parent

The parent Device or None, if there is no parent device.

children

Yield all direct children of this device.

Note

As the underlying library does not provide any means to directly query the children of a device, this property performs a linear search through all devices.

Return an iterable yielding a Device object for each direct child of this device.

Required udev version: 172

Changed in version 0.13: Requires udev version 172 now.

traverse()

Traverse all parent devices of this device from bottom to top.

Return an iterable yielding all parent devices as Device objects, not including the current device. The last yielded Device is the top of the device hierarchy.

find_parent(subsystem, device_type=None)

Find the parent device with the given subsystem and device_type.

subsystem is a byte or unicode string containing the name of the subsystem, in which to search for the parent. device_type is a byte or unicode string holding the expected device type of the parent. It can be None (the default), which means, that no specific device type is expected.

Return a parent Device within the given subsystem and – if device_type is not None – with the given device_type, or None, if this device has no parent device matching these constraints.

New in version 0.9.

Device properties

__iter__()

Iterate over the names of all properties defined for this device.

Return a generator yielding the names of all properties of this device as unicode strings.

__len__()

Return the amount of properties defined for this device as integer.

__getitem__(property)

Get the given property from this device.

property is a unicode or byte string containing the name of the property.

Return the property value as unicode string, or raise a KeyError, if the given property is not defined for this device.

asint(property)

Get the given property from this device as integer.

property is a unicode or byte string containing the name of the property.

Return the property value as integer. Raise a KeyError, if the given property is not defined for this device, or a ValueError, if the property value cannot be converted to an integer.

asbool(property)

Get the given property from this device as boolean.

A boolean property has either a value of '1' or of '0', where '1' stands for True, and '0' for False. Any other value causes a ValueError to be raised.

property is a unicode or byte string containing the name of the property.

Return True, if the property value is '1' and False, if the property value is '0'. Any other value raises a ValueError. Raise a KeyError, if the given property is not defined for this device.

Sysfs attributes

attributes

The system attributes of this device as read-only Attributes mapping.

System attributes are basically normal files inside the the device directory. These files contain all sorts of information about the device, which may not be reflected by properties. These attributes are commonly used for matching in udev rules, and can be printed using udevadm info --attribute-walk.

The values of these attributes are not always proper strings, and can contain arbitrary bytes.

New in version 0.5.

class pyudev.Attributes

A mapping which holds udev attributes for Device objects.

This class subclasses the Mapping ABC, providing a read-only dictionary mapping attribute names to the corresponding values. Therefore all well-known dicitionary methods and operators (e.g. .keys(), .items(), in) are available to access device attributes.

New in version 0.5.

device

The Device to which these attributes belong.

__iter__()

Iterate over all attributes defined.

Yield each attribute name as unicode string.

__len__()

Return the amount of attributes defined.

__getitem__(attribute)

Get the given system attribute for the device.

attribute is a unicode or byte string containing the name of the system attribute.

Return the attribute value as byte string, or raise a KeyError, if the given attribute is not defined for this device.

asstring(attribute)

Get the given atribute for the device as unicode string.

Depending on the content of the attribute, this may or may not work. Be prepared to catch UnicodeDecodeError.

attribute is a unicode or byte string containing the name of the attribute.

Return the attribute value as byte string. Raise a KeyError, if the given attribute is not defined for this device, or UnicodeDecodeError, if the content of the attribute cannot be decoded into a unicode string.

asint(attribute)

Get the given attribute as integer.

attribute is a unicode or byte string containing the name of the attribute.

Return the attribute value as integer. Raise a KeyError, if the given attribute is not defined for this device, or a ValueError, if the attribute value cannot be converted to an integer.

asbool(attribute)

Get the given attribute from this device as boolean.

A boolean attribute has either a value of '1' or of '0', where '1' stands for True, and '0' for False. Any other value causes a ValueError to be raised.

attribute is a unicode or byte string containing the name of the attribute.

Return True, if the attribute value is '1' and False, if the attribute value is '0'. Any other value raises a ValueError. Raise a KeyError, if the given attribute is not defined for this device.

class pyudev.Tags

A iterable over Device tags.

Subclasses the Container and the Iterable ABC.

__iter__()

Iterate over all tags.

Yield each tag as unicode string.

__contains__(tag)

Check for existence of tag.

tag is a tag as unicode string.

Return True, if tag is attached to the device, False otherwise.

Device exceptions

class pyudev.DeviceNotFoundError

An error indicating that no Device was found.

Changed in version 0.5: Renamed from NoSuchDeviceError to its current name.

class pyudev.DeviceNotFoundAtPathError(sys_path)

A DeviceNotFoundError indicating that no Device was found at a given path.

sys_path

The path that caused this error as string.

class pyudev.DeviceNotFoundByNameError(subsystem, sys_name)

A DeviceNotFoundError indicating that no Device was found with a given name.

subsystem

The subsystem that caused this error as string.

sys_name

The sys name that caused this error as string.

class pyudev.DeviceNotFoundByNumberError(type, number)

A DeviceNotFoundError indicating, that no Device was found for a given device number.

device_number

The device number causing this error as integer.

device_type

The device type causing this error as string. Either 'char' or 'block'.

class pyudev.DeviceNotFoundInEnvironmentError

A DeviceNotFoundError indicating, that no Device could be constructed from the process environment.

Monitor – device monitoring

class pyudev.Monitor

Monitor udev events:

>>> context = pyudev.Context()
>>> monitor = pyudev.Monitor.from_netlink(context)
>>> monitor.filter_by(subsystem='input')
>>> for action, device in monitor:
...     print('{0}: {1}'.format(action, device))
...

A Monitor objects connects to the udev daemon and listens for changes to the device list. A monitor is created by connecting to the kernel daemon through netlink (see from_netlink()). Alternatively, connections to arbitrary daemons can be made using from_socket(), which is however only seldom of use.

Once the monitor is created, you can add a filter using filter_by() or filter_by_tag() to drop incoming events in subsystems, which are not of interest to the application.

If the monitor is eventually set up, you can either iterate over the Monitor object to synchronously receive events (see __iter__()) or use a MonitorObserver to asynchronously react on events. Moreover the monitor provides a real file descriptor (see fileno()), which is selectable, so you can also plug the monitor into custom notification mechanisms. Do not read or write on this file descriptor.

Instances of this class can directly be given as udev_monitor * to functions wrapped through ctypes.

Create a monitor by connecting to the kernel daemon through netlink.

context is the Context to use. source is a string, describing the event source. Two sources are available:

'udev' (the default)
Events emitted after udev as registered and configured the device. This is the absolutely recommended source for applications.
'kernel'
Events emitted directly after the kernel has seen the device. The device has not yet been configured by udev and might not be usable at all. Never use this, unless you know what you are doing.

Return a new Monitor object, which is connected to the given source. Raise ValueError, if an invalid source has been specified. Raise EnvironmentError, if the creation of the monitor failed.

classmethod from_socket(context, socket_path)

Connect to an arbitrary udev daemon using the given socket_path.

context is the Context to use. socket_path is a byte or unicode string, pointing to an existing socket. If the path starts with a @, use an abstract namespace socket. If socket_path does not exist, fall back to an abstract namespace socket.

The caller is responsible for permissions and cleanup of the socket file.

Return a new Monitor object, which is connected to the given socket. Raise EnvironmentError, if the creation of the monitor failed.

context

The Context to which this monitor is bound.

New in version 0.5.

fileno()

Return the file description associated with this monitor as integer.

This is really a real file descriptor ;), which can be watched and select.select()ed.

filter_by(subsystem, device_type=None)

Filter incoming events.

subsystem is a byte or unicode string with the name of a subsystem (e.g. 'input'). Only events originating from the given subsystem pass the filter and are handed to the caller.

If given, device_type is a byte or unicode string specifying the device type. Only devices with the given device type are propagated to the caller. If device_type is not given, no additional filter for a specific device type is installed.

These filters are executed inside the kernel, and client processes will usually not be woken up for device, that do not match these filters.

Changed in version 0.15: This method can also be after enable_receiving() now

filter_by_tag(tag)

Filter incoming events by the given tag.

tag is a byte or unicode string with the name of a tag. Only events for devices which have this tag attached pass the filter and are handed to the caller.

Like with filter_by() this filter is also executed inside the kernel, so that client processes are usually not woken up for devices without the given tag.

Required udev version: 154

New in version 0.9.

Changed in version 0.15: This method can also be after enable_receiving() now

remove_filter()

Remove any filters installed with filter_by() or filter_by_tag() from this monitor.

Warning

Up to udev 181 (and possibly even later versions) the underlying udev_monitor_filter_remove() seems to be broken. If used with affected versions this method always raises ValueError.

Raise EnvironmentError if removal of installed filters failed.

New in version 0.15.

enable_receiving()

Switch the monitor into listing mode.

Connect to the event source and receive incoming events. Only after calling this method, the monitor listens for incoming events.

Note

This method is implicitly called by __iter__(). You don’t need to call it explicitly, if you are iterating over the monitor.

start()

Alias for enable_receiving()

set_receive_buffer_size(size)

Set the receive buffer size.

size is the requested buffer size in bytes, as integer.

Note

The CAP_NET_ADMIN capability must be contained in the effective capability set of the caller for this method to succeed. Otherwise EnvironmentError will be raised, with errno set to EPERM. Unprivileged processes typically lack this capability. You can check the capabilities of the current process with the python-prctl module:

>>> import prctl
>>> prctl.cap_effective.net_admin

Raise EnvironmentError, if the buffer size could not bet set.

New in version 0.13.

receive_device()

Receive a single device from the monitor.

The caller must make sure, that there are events available in the event queue. The call blocks, until a device is available.

If a device was available, return (action, device). device is the Device object describing the device. action is a string describing the action. udev informs about the following actions:

'add'
A device has been added (e.g. a USB device was plugged in)
'remove'
A device has been removed (e.g. a USB device was unplugged)
'change'
Something about the device changed (e.g. a device property)
'move'
The device was renamed, moved, or re-parented

Raise EnvironmentError, if no device could be read.

__iter__()

Wait for incoming events and receive them upon arrival.

This methods implicitly calls enable_receiving(), and starts polling the fileno() of this monitor. If a event comes in, it receives the corresponding device and yields it to the caller.

The returned iterator is endless, and continues receiving devices without ever stopping.

Yields (action, device) (see receive_device() for a description).

MonitorObserver – asynchronous device monitoring

class pyudev.MonitorObserver(monitor, event_handler, *args, **kwargs)

A Thread class to observe a Monitor in background:

>>> context = pyudev.Context()
>>> monitor = pyudev.Monitor.from_netlink(context)
>>> monitor.filter_by(subsystem='input')
>>> def print_device_event(action, device):
...     print('background event {0}: {1}'.format(action, device))
>>> observer = MonitorObserver(monitor, print_device_event, name='monitor-observer')
>>> observer.daemon
True
>>> observer.start()

In the above example, input device events will be printed in background, until stop() is called on observer.

Note

Instances of this class are always created as daemon thread. If you do not want to use daemon threads for monitoring, you need explicitly set daemon to False before invoking start().

New in version 0.14.

Changed in version 0.15: Monitor.enable_receiving() is implicitly called when the thread is started.

monitor

Get the Monitor observer by this object.

__init__(monitor, event_handler, *args, **kwargs)

Create a new observer for the given monitor.

monitor is the Monitor to observe. event_handler is a callable with the signature event_handler(action, device), where action is a string describing the event (see Monitor.receive_device()), and device is the Device object that caused this event. This callable is invoked for every device event received through monitor.

Warning

event_handler is always invoked in this background thread, and not in the calling thread.

args and kwargs are passed unchanged to the parent constructor of Thread.

send_stop()

Send a stop signal to the background thread.

The background thread will eventually exit, but it may still be running when this method returns. This method is essentially the asynchronous equivalent to stop().

Note

The underlying monitor is not stopped.

stop()

Stop the background thread.

Warning

Calling this method from the event_handler results in a dead lock. If you need to stop the observer from event_handler, use send_stop(), and be prepared to get some more events before the observer actually exits.

Send a stop signal to the backgroud (see send_stop()) and waits for the background thread to exit (see join()). After this method returns, it is guaranteed that the event_handler passed to MonitorObserver.__init__() is not longer called for any event from monitor.

Note

The underlying monitor is not stopped.