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

Primer to Python multiprocessing, multithreading, and asyncio
Oct 24th, 2018
Method delegation in Python
Jul 11th, 2018
Using Python enums in SQLAlchemy models
May 16th, 2018
Python command-line scripts with argparse
Feb 15th, 2018
SQLAlchemy commit(), flush(), expire(), refresh(), merge() - what's the difference?
Nov 2nd, 2017