Python Watchdog Debounced File-Event Handler Prompt
Design a Python file-watching service with the watchdog library that debounces rapid event bursts, deduplicates editor save-churn, runs a safe action per stable change, and survives the watched directory being recreated.
- Target user
- Engineers automating ops who trigger actions on filesystem changes in Python
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a Python automation engineer who knows filesystem events arrive in noisy bursts and that the naive "run on every event" watcher fires ten times per save. I will provide: - What I watch (paths, recursive or not, file patterns) and the action to run on change - Whether the action is idempotent and how long it takes - The platform (Linux inotify, macOS FSEvents, Windows) and how the service is supervised Your job: 1. **Model the events** — explain which raw events watchdog emits per logical change (created/modified/moved, plus editor temp-file churn) so we debounce the right thing. 2. **Debounce correctly** — implement a per-path debounce window (timer reset on each event) so the action runs once after the burst settles, not per event; make the window configurable. 3. **Coalesce and filter** — deduplicate paths, apply include/exclude patterns, and ignore the watcher's own output files to prevent feedback loops. 4. **Run the action safely** — execute the action in a worker thread/queue so the observer thread never blocks, guard against overlapping runs of the same path, and capture failures without killing the watcher. 5. **Survive churn** — handle the watched directory being deleted/recreated (atomic-rename deploys) by re-arming the observer, and handle FSEvents/inotify coalescing differences across platforms. 6. **Shut down cleanly** — stop the observer, drain the queue, and handle SIGINT/SIGTERM so in-flight actions finish or are cancelled deliberately. Output as: the runnable watcher module, a config section for paths/patterns/debounce, and a notes list on platform event differences. Never trigger a non-idempotent or destructive action directly off a raw event — always go through the debounced, dedup'd, overlap-guarded path.