Using Python's Watchdog to monitor changes to a directory

Feb 22nd, 2016 in  by Michael Cho

A small Python script to take action whenever a new file is uploaded to a directory or its contents change.

Watchdog is a handy Python package which uses the inotify Linux kernel subsystem to watch for any changes to the filesystem.

This makes it an excellent foundation to build a a small script which takes action whenever a file is received in a directory, or any of the directory's contents change. An example might be a client-facing sftp server where you may want to receive an email when a file is received.

I've included a shortened version of a watcher.py script I used for just such a purpose. There are 2 main classes:

  1. Watcher - this waits for any events on the watched directory
  2. Handler - this is the event handler that takes action when an event is received

import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


class Watcher:
    DIRECTORY_TO_WATCH = "/path/to/my/directory"

    def __init__(self):
        self.observer = Observer()

    def run(self):
        event_handler = Handler()
        self.observer.schedule(event_handler, self.DIRECTORY_TO_WATCH, recursive=True)
        self.observer.start()
        try:
            while True:
                time.sleep(5)
        except:
            self.observer.stop()
            print "Error"

        self.observer.join()


class Handler(FileSystemEventHandler):

    @staticmethod
    def on_any_event(event):
        if event.is_directory:
            return None

        elif event.event_type == 'created':
            # Take any action here when a file is first created.
            print "Received created event - %s." % event.src_path

        elif event.event_type == 'modified':
            # Taken any action here when a file is modified.
            print "Received modified event - %s." % event.src_path


if __name__ == '__main__':
    w = Watcher()
    w.run()

To use this, just run python watcher.py from your console. If you open any console window and upload a file or make any changes, you will see this printed out in your original console window. 

To actually make this useful, you should wrap this up as a daemon or upstart script which can be run indefinitely. 


Other articles you may like

SQLAlchemy commit(), flush(), expire(), refresh(), merge() - what's the difference?
Nov 2nd, 2017
Prioritized Code Review Checklist - what to look for first, second, and last
Sep 21st, 2017
Many to many relationships in SQLAlchemy models (Flask)
Jul 28th, 2017
Bash script to relink alembic migrations
Jun 12th, 2017
Using model callbacks in SQLAlchemy to generate slugs
Feb 7th, 2017