Today I want to show how can you monitor changes of a directory with watchdog
. It is a Python module that monitors our filesystem looking for any changes (like the creation, change, or deletion of a file or of a directory). When a change occurs, the watchdog
reports it to us via specific event that we can handle. So for example, if you need to watch a log file for changes this module is perfect, or if you had a configuration file that is been changed you can also use this module to track that.
First of all, you need to install Watchdog
via pip
:
pip install watchdog
After that we need to make import
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
After that we need to create an event handler, basically is the object that will be notified when something happens on the folder that we are monitoring. Also we need another object, known as the observer
, that will monitor our filesystem, looking for changes that will be handled by the event handler.
if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='C:\\Users\\Stokry\Desktop\\test', recursive=False)
observer.start()
Now that we have created the handler and observer we need to write the code we want to run when the events occur.
Let’s start creating three different functions that will be used when a file is modified, created, or deleted. We can also add function when something is moved.
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')
def on_created(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')
def on_deleted(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')
Putting all together:
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')
def on_created(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')
def on_deleted(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')
if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='C:\\Users\\Stokry\Desktop\\test', recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Now we can test this out.
Let's say we delete the file, the output is like this:
event type: deleted path : C:\Users\Stokry\Desktop\test\log_old.txt
Thank you all.
Top comments (3)
Does the code require the sleep? If not, it should be doing some other sort of work. Perhaps putting an event in a queue and waiting on that.
Yes, the
time.sleep(1)
is used to keep the program running in a loop, continuously checking for filesystem events. Without this sleep, the program would exit immediately, and the observer would not have a chance to detect any events. However, I agree that the code could be enhanced to utilize a more event-driven approach rather than a simple sleep. An alternative approach could involve using an event queue and waiting for an event to be added to the queue, but in this particular context, the sleep function serves the purpose of keeping the application alive without adding unnecessary complexity.Thank You for this interesting post. I am also trying to achieve more without JavaScript.
When writing a new app you don't necessarily want to deploy a flask framework just to test your ideas.Since you can not easily pass variables between JavaScript and Python one way to achieve this is to create a JSON file from a JavaScript HTML element and read the JSON file from your python app. This is where I needed a way to detect a JSON file change. Your post came in really handy for me.
I am just wondering about the additional machine workload induced by the monitoring though..