Watchdog Gevent Observer
watchdog-gevent is a Python library that provides a gevent-based observer for the `watchdog` file system monitoring library. It allows `watchdog` to function efficiently within a gevent cooperative multitasking environment, replacing the default threading-based observer. The current version is 0.2.1, with recent updates in late 2024, indicating an active but low-cadence maintenance.
Warnings
- breaking `watchdog-gevent` fundamentally relies on `gevent.monkey.patch_all()` being called at the very beginning of your application. Failure to do so, or patching too late, will result in the observer not functioning correctly or blocking the gevent event loop.
- gotcha This library explicitly notes that it does not emit file and directory move (rename) events. If your application requires detecting these specific event types, `watchdog-gevent` will not provide them.
- gotcha As a gevent-based library, running CPU-intensive synchronous code within a greenlet can block the entire gevent event loop, leading to 'greenlet starvation' and unresponsiveness. This is a common pitfall in gevent applications.
- compatibility `watchdog-gevent` itself states dependencies on `watchdog` (0.8+) and `gevent` (1.1+). However, recent versions of the underlying `watchdog` and `gevent` libraries (e.g., watchdog 3.0.0+, gevent 25.9.2.dev0+) officially support Python 3.9 and newer. Ensure your Python environment meets these transitive requirements.
Install
-
pip install watchdog-gevent
Imports
- Observer
from watchdog_gevent import Observer
- FileSystemEventHandler
from watchdog.events import FileSystemEventHandler
- monkey.patch_all
import gevent.monkey; gevent.monkey.patch_all()
Quickstart
import time
import os
import gevent.monkey
from watchdog.events import FileSystemEventHandler
from watchdog_gevent import Observer
# IMPORTANT: Apply gevent monkey patching BEFORE importing other blocking libraries
gevent.monkey.patch_all()
class MyHandler(FileSystemEventHandler):
def on_created(self, event):
print(f"Gevent: File created: {event.src_path}")
def on_deleted(self, event):
print(f"Gevent: File deleted: {event.src_path}")
def on_modified(self, event):
print(f"Gevent: File modified: {event.src_path}")
# Note: watchdog-gevent does not emit on_moved events.
# def on_moved(self, event):
# print(f"Gevent: File moved from {event.src_path} to {event.dest_path}")
if __name__ == "__main__":
# Create a temporary directory for demonstration
path = os.path.join(os.getcwd(), "gevent_test_dir")
os.makedirs(path, exist_ok=True)
print(f"Monitoring directory: {path}")
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1) # gevent.sleep(1) would also work after monkey-patching
except KeyboardInterrupt:
observer.stop()
observer.join()
print("Observer stopped.")
# Clean up
os.rmdir(path)