watchdog.observers.Observer works in Windows, works in docker on Linux, does not work in docker on Windows

Docker Windows Volume Watcher

It is also possible to use Docker Windows Volume Watcher. The Python script monitors folder bindings of Docker containers hosted on Windows and updates those containers with file changes.

Install using pip (supports Python 2 & 3).

pip install docker-windows-volume-watcher

Monitor all directory bindings of all containers.

docker-volume-watcher

Monitor only bindings of container container_name.

docker-volume-watcher container_name

Monitor only binding of container_name to host directory C:\some\directory.

docker-volume-watcher container_name C:\some\directory

Limitations

  • The script doesn't propagate to container file deletion events.
  • The script requires stat and chmod utils to be installed in container.

https://forums.docker.com/t/file-system-watch-does-not-work-with-mounted-volumes/12038/9 http://blog.subjectify.us/miscellaneous/2017/04/24/docker-for-windows-watch-bindings.html

watchdog and PollingObserver()

Another solution is to use the class PollingObserver. But it is significantly slower if the watchdog has to monitor multiple files and folders with one schedule.

import sys
import time
import logging
from watchdog.observers.polling import PollingObserver
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    event_handler = LoggingEventHandler()
    observer = PollingObserver()
    # Limit the number of files by setup multiple schedule
    observer.schedule(event_handler, '/folder/subfolder') # All files in a subfolder
    observer.schedule(event_handler, '/folder/file') # A file
    observer.schedule(event_handler, '/folder/file2') # A file
    # etc...
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

The underlying API that watchdog uses to monitor linux filesystem events is called inotify. The Docker for Windows WSL 2 backend documentation notes:

Linux containers only receive file change events (“inotify events”) if the original files are stored in the Linux filesystem.

The directory you're mounting, c:\My_MR, resides on the Windows file system and thus inotify inside the watcher container doesn't work.

Instead, you can run docker from inside your WSL 2 default distribution with a linux filesystem path, e.g., ~/my_mr:

docker run -d --network onprem_network -v ~/my_mr:/code/My_MR --name watcher watcher 
docker run -d --network onprem_network -v ~/my_mr:/code/My_MR --name parser parser 

This directory can be accessed from Windows while that WSL 2 distribution is running using the \\wsl$\ network path, i.e., \\wsl$\<Distro name>\home\<username>\my_mr (more info here). Accordingly, I believe docker run could also be used from Windows using the \\wsl$\ path with -v.