Watchdog
Watchdog is a Python library and shell utility that provides an API for monitoring file system events in real-time. It supports various operating systems by utilizing native APIs like inotify (Linux), FSEvents (macOS), and ReadDirectoryChangesW (Windows), falling back to polling when native APIs are unavailable. Currently at version 6.0.0, the library maintains an active development pace with major releases approximately annually.
Warnings
- breaking Python 3.8 support was dropped in Watchdog v5.0.0. Python 3.7 support was dropped in v4.0.0. Ensure your Python environment is 3.9 or newer.
- breaking In v5.0.0, several core classes and exceptions were renamed (e.g., `BaseObserverSubclassCallable` to `ObserverType`, `UnsupportedLibc` to `UnsupportedLibcError`). Keyword arguments are now enforced in core API calls. `InotifyConstants.IN_CLOSE` was also removed.
- breaking In v6.0.0, the `inotify` backend now uses `select.poll()` instead of the deprecated `select.select()`, if available. Additionally, several unused functions from the `watchdog.utils.echo` module were removed.
- gotcha Text editors like Vim often write to temporary files and then swap them in to replace the original, which may not trigger `on_modified` events.
- gotcha On BSD/macOS systems using `kqueue`, Watchdog opens file descriptors for monitored items. Hitting the operating system's maximum open file descriptor limit can prevent Watchdog from monitoring new files or directories.
- gotcha On Windows, the `ReadDirectoryChangesW` API has limitations: rename/movement events for directories may be reported before I/O is complete, and delete events for directories might be reported as file deletion events.
Install
-
pip install watchdog -
pip install 'watchdog[watchmedo]'
Imports
- Observer
from watchdog.observers import Observer
- FileSystemEventHandler
from watchdog.events import FileSystemEventHandler
- LoggingEventHandler
from watchdog.events import LoggingEventHandler
Quickstart
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class MyEventHandler(FileSystemEventHandler):
def on_any_event(self, event):
# Log any event for demonstration
print(f"Event type: {event.event_type} | Path: {event.src_path} | Is directory: {event.is_directory}")
if __name__ == "__main__":
path_to_watch = "."
event_handler = MyEventHandler()
observer = Observer()
observer.schedule(event_handler, path_to_watch, recursive=True)
observer.start()
try:
print(f"Monitoring directory: {path_to_watch}")
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()