Skip to main content

Watchinotify

Watchinotify is a python library to easily use the libc's inotify functions to watch for any file interaction.

The library aims at being simple yet powerfull with easily auditable code.

Limitations

If you watch a file or a folder for a move it will be unwatched after being moved (renaming is considered a move). This is a limitation of the inotify system which desn't give any way to know the new name/path. Any move/rename within watched folders are still being tracked, this also works with the recursive option.

When using the recursive option the folder SUB_CREATED and SUB_MOVED events are enforced. Otherwise the watcher would not be able to keep track of the file tree after adding or moving folders.

Install

Use pip or equivalent to install package name watchinotify:

pip install watchinotify

Usage

Create a Watcher and assign its callback to your custom function, then with the Watcher's watch function to add a list (or any iterable) or path to file/folder to watch. The watcher is going to run on a separated thread waiting for any event then calling the callback. You can run your code after calling watch or wait for an event using the threading.Event for instance.

The following example explicits the parameters types of the callback function:

from pathlib import Path
import threading

from watchinotify import Watcher

event_received = threading.Event()

def callback(path: Path | None, event, name: bytes):
    print(f'New event {event} from path {path} with additionnal name {name.decode()}')
    event_received.set()

watcher = Watcher() as watcher:
watcher.watch([Path('/path/to/watch')])
watcher.callback = callback
# Any of your code from here
event_received.wait()

# Do not forget to close the watcher once done (or use a 'with' statement)
watcher.close()

Using a with statement is easier and safer so the close will be automatically called.

with Watcher(event_type, exclude_patterns, recursive) as watcher:  # will automatically close
    watcher.watch([Path('/path/to/watch')])

The Watcher has 3 arguments:

  • event_type : what type of event to watch see the *Event Type section below. If set to None it is using default value of FileEvent.MODIFIED | FileEvent.DELETED | FileEvent.MOVED for files and FolderEvent.DELETED | FolderEvent.MOVED | FolderEvent.SUB_CREATED | FolderEvent.SUB_DELETED | FolderEvent.SUB_MOVED for folders. You can use the parent Event type to set all required events, if you want specific events separated it is better to create multiple watchers. Default: None
  • exclude_patterns : iterable (list, tuple, etc) of pattern to ignore,following glob conventions, example : ['*/sub_folder', __pycache__]. Default: None
  • recursive : boolean to watch recursively all sub folders/files when adding a folder to watch. This will force the events FolderEvent.SUB_CREATED and FolderEvent.SUB_MOVED to be watched in order to properly work, you'll have to filter out those event in you callback if unwanted. Default: True

Event Types

All possible events are un the Event flag. You can cumulate events by using the or or | operator. 2 additionnal types FileEvent and FolderEvent inherits from the Event values but only contains the event that can be trigger respectively from files and folders. The 2 sub types also have an ALL value as a handy shortcut.

The events are defined as:

from enum import IntFlag, auto

class Event(IntFlag):
    OPENED = auto()
    MODIFIED = auto()
    DELETED = auto()
    MOVED = auto()
    CLOSED = auto()
    SUB_CREATED = auto()
    SUB_DELETED = auto()
    SUB_MOVED = auto()


class FileEvent(IntFlag):
    OPENED = Event.OPENED.value
    MODIFIED = Event.MODIFIED.value
    DELETED = Event.DELETED.value
    MOVED = Event.MOVED.value
    CLOSED = Event.CLOSED.value

    ALL = OPENED | MODIFIED | DELETED | MOVED | CLOSED


class FolderEvent(IntFlag):
    DELETED = Event.DELETED.value
    MOVED = Event.MOVED.value
    SUB_CREATED = Event.SUB_CREATED.value
    SUB_DELETED = Event.SUB_DELETED.value
    SUB_MOVED = Event.SUB_MOVED.value

    ALL = DELETED | MOVED | SUB_CREATED | SUB_DELETED | SUB_MOVED

Development

Run test

pytest

Run coverage

python tests/run_coverage.py

LICENSE

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

watchinotify-0.2.1.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

watchinotify-0.2.1-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file watchinotify-0.2.1.tar.gz.

File metadata

  • Download URL: watchinotify-0.2.1.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for watchinotify-0.2.1.tar.gz
Algorithm Hash digest
SHA256 d12655a91eb521bb751d15118187a98e26cadae941e35301ebe30fdae5b6194a
MD5 29f6984fb1cbeea3cf9926be01175db7
BLAKE2b-256 1c76eaf6899ba1f1531833821ff918423439c4ecd979ee0fecc289bf70c1db44

See more details on using hashes here.

File details

Details for the file watchinotify-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: watchinotify-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for watchinotify-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3196381f406e5e5deece55fd1fd54c6ea02f1d0cb725b9a31f20dd605ffc4741
MD5 aa30778bf743b7ff418f027c21c9ab0a
BLAKE2b-256 b8b5a993edaa5c7c752b4b6ffeb04eb0e6e7d1f3c2c0d7ec40360b57e6f22887

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.0

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page