{"id":4847,"library":"watchdog-gevent","title":"Watchdog Gevent Observer","description":"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.","status":"active","version":"0.2.1","language":"en","source_language":"en","source_url":"https://github.com/Bogdanp/watchdog_gevent","tags":["gevent","watchdog","file system monitoring","async","greenlet"],"install":[{"cmd":"pip install watchdog-gevent","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core file system monitoring library. Requires version 0.8+ for watchdog-gevent. Current watchdog versions (3.0.0+) require Python 3.9+.","package":"watchdog","optional":false},{"reason":"Asynchronous I/O framework. Requires version 1.1+ for watchdog-gevent. Current gevent versions (25.9.2.dev0+) require Python 3.9+.","package":"gevent","optional":false}],"imports":[{"note":"This is the gevent-specific observer class.","symbol":"Observer","correct":"from watchdog_gevent import Observer"},{"note":"Standard event handler from the core watchdog library.","symbol":"FileSystemEventHandler","correct":"from watchdog.events import FileSystemEventHandler"},{"note":"gevent.monkey.patch_all() must be called early in the application's lifecycle, before other modules that might use standard blocking I/O or threading functions are imported, for watchdog-gevent to work correctly.","wrong":"import gevent.monkey; # then import other modules","symbol":"monkey.patch_all","correct":"import gevent.monkey; gevent.monkey.patch_all()"}],"quickstart":{"code":"import time\nimport os\nimport gevent.monkey\nfrom watchdog.events import FileSystemEventHandler\nfrom watchdog_gevent import Observer\n\n# IMPORTANT: Apply gevent monkey patching BEFORE importing other blocking libraries\ngevent.monkey.patch_all()\n\nclass MyHandler(FileSystemEventHandler):\n    def on_created(self, event):\n        print(f\"Gevent: File created: {event.src_path}\")\n\n    def on_deleted(self, event):\n        print(f\"Gevent: File deleted: {event.src_path}\")\n\n    def on_modified(self, event):\n        print(f\"Gevent: File modified: {event.src_path}\")\n\n    # Note: watchdog-gevent does not emit on_moved events.\n    # def on_moved(self, event):\n    #     print(f\"Gevent: File moved from {event.src_path} to {event.dest_path}\")\n\nif __name__ == \"__main__\":\n    # Create a temporary directory for demonstration\n    path = os.path.join(os.getcwd(), \"gevent_test_dir\")\n    os.makedirs(path, exist_ok=True)\n    print(f\"Monitoring directory: {path}\")\n\n    event_handler = MyHandler()\n    observer = Observer()\n    observer.schedule(event_handler, path, recursive=True)\n    observer.start()\n\n    try:\n        while True:\n            time.sleep(1) # gevent.sleep(1) would also work after monkey-patching\n    except KeyboardInterrupt:\n        observer.stop()\n    observer.join()\n    print(\"Observer stopped.\")\n\n    # Clean up\n    os.rmdir(path)\n","lang":"python","description":"This quickstart demonstrates how to use `watchdog-gevent` to monitor a directory. It's crucial to apply `gevent.monkey.patch_all()` at the very beginning of your script, before importing other modules that might rely on blocking I/O or threading, to ensure the gevent observer functions correctly within the cooperative multitasking environment. The example creates a temporary directory, sets up an observer, and prints messages for file creation, deletion, and modification events."},"warnings":[{"fix":"Ensure `import gevent.monkey; gevent.monkey.patch_all()` is the first significant code executed in your application, before any other I/O or threading-related imports.","message":"`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.","severity":"breaking","affected_versions":"<=0.2.1"},{"fix":"Implement custom logic using `on_created` and `on_deleted` events to infer moves, or consider using the standard `watchdog` observers if `gevent` compatibility for move events is not a strict requirement.","message":"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.","severity":"gotcha","affected_versions":"<=0.2.1"},{"fix":"Offload CPU-bound tasks to separate processes or threads using `gevent.threadpool`, or ensure CPU-intensive operations are non-blocking. File I/O, even with monkey-patching, can be blocking on some operating systems; use `gevent.threadpool` for concurrent file I/O.","message":"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.","severity":"gotcha","affected_versions":"All"},{"fix":"Use Python 3.9 or newer. Consult the documentation for `watchdog` and `gevent` for their current Python version requirements.","message":"`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.","severity":"compatibility","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}