Skip to main content

Simple and powerfull file watcher using libc's inotify

Project description

FileWatch

FileWatch 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/.

Project details


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.0.tar.gz (24.5 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.0-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: watchinotify-0.2.0.tar.gz
  • Upload date:
  • Size: 24.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for watchinotify-0.2.0.tar.gz
Algorithm Hash digest
SHA256 104841902c52411a45714251753f0d0a27f792eea0741bd8e41749062d35c2ec
MD5 dcf426673288e9a82edb14fa6db06303
BLAKE2b-256 d39173ddad42d93055522a3990f5e027ef968e8bb0d3f9f4d4599f3a26b14a85

See more details on using hashes here.

File details

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

File metadata

  • Download URL: watchinotify-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for watchinotify-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ceb69d8e71de2a1dbf5b52fb780820f33c1f1f62a3ff8dc4f1f2eb7bdc792b4a
MD5 f1d9a15d92f17476f5ca42367719a4f9
BLAKE2b-256 bde60f31687d5109064332d7a7526cd538afe434195e09db9d8f15de6a56fa87

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page