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 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 import FileSystemEventHandler

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

    def __init__(self): = Observer()

    def run(self):
        event_handler = Handler(), self.DIRECTORY_TO_WATCH, recursive=True)
            while True:
            print "Error"

class Handler(FileSystemEventHandler):

    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()

To use this, just run python 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

Python command-line scripts with argparse
Feb 15th, 2018
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