watchdog.observators.observator在Windows中工作,在Linux上的docker中工作,在Windows上的docker中不工作

2024-04-25 05:13:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个让我发疯的有趣问题。我有一个使用watchdog.observators.observator的python程序。该程序(又名watcher)监视文件夹,并在其中出现文件时作出响应。我有另一个程序(aka parser),它定期用文件填充关注的文件夹

  1. 当watcher程序在Windows中运行,解析器在Windows上的docker容器中运行时,就有了幸福
  2. 当watcher程序在Linux机器上的docker容器中运行,而解析器在Linux机器上的另一个docker容器中运行时,就有了幸福
  3. 当watcher程序在Windows上的docker容器中运行,而解析器在Windows上的另一个docker容器中运行时,幸福感是无法实现的。解析器用文件填充文件夹,但观察者从不观察它们

这是我的观察者代码:

import os
import sys
import time
   
from watchdog.observers import Observer
from event_handler import ImagesEventHandler
from constants import ROOT_FOLDER, IMAGES_FOLDER, CWD


class ImagesWatcher:
    def __init__(self, src_path):
        self.__src_path = src_path
        print(self.__src_path)
        self.__event_handler = ImagesEventHandler()
        self.__event_observer = Observer()
        print("********** Inside ImagesWatcher --init__ method just after instantiating ImagesEventHandler and Observer **************")

    def run(self):
        print("********** Inside ImagesWatcher run method **************")
        self.start()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            self.stop()

    def start(self):
        print("********** Inside ImagesWatcher start method **************")
        self.__schedule()
        self.__event_observer.start()

    def stop(self):
        print("********** Inside ImagesWatcher stop method **************")
        self.__event_observer.stop()
        self.__event_observer.join()

    def __schedule(self):
        print("********** Inside ImagesWatcher __schedule method **************")
        print(self.__src_path)
        self.__event_observer.schedule(
            self.__event_handler,
            self.__src_path,
            recursive=True
        )

if __name__ == "__main__":
    src_path = sys.argv[1] if len(sys.argv) > 1 else CWD
    src_path = os.path.abspath(src_path)
    watch_path = os.path.join(src_path, ROOT_FOLDER)
    watch_path = os.path.join(watch_path, IMAGES_FOLDER)
    print('watch_path: ' + watch_path)

    if not os.path.exists(watch_path):
        os.makedirs(watch_path)
        print('just created: ' + watch_path)

    ImagesWatcher(watch_path).run()

以下是关联的事件处理程序代码:

import os
from PIL import Image
from watchdog.events import FileSystemEventHandler
from lambda_function import lambda_handler
from time import sleep
from os.path import dirname, abspath

class ImagesEventHandler(FileSystemEventHandler):

    def __init__(self,):
        print("********** Inside event handler __init__ method **************")
    
    def on_created(self, event):
        print("********** Inside event handler on_created method **************")
        self.process(event)

    def process(self, event):
        print("********** Inside event handler process method **************")
        sleep(2)
        image = Image.open(event.src_path)
        tracking_dir=os.path.join(dirname(dirname(abspath(event.src_path))),'Tracking')
        print("********************  tracking_dir: ' + tracking_dir + ' ********************")
        lambda_handler(image,tracking_dir)

监视程序的停止方法永远不会执行。执行事件处理程序的init方法,但既不执行on_,也不执行process方法

以下是我如何构建和运行docker容器:

docker build -t watcher -f docker/watcher/Dockerfile . 
docker run -d --network onprem_network -v c:\My_MR:/code/My_MR --name watcher watcher 

docker build -t parser -f docker/parser/Dockerfile . 
docker run -d --network onprem_network -v c:\My_MR:/code/My_MR --name parser parser 

我的观察者Dockerfile:

FROM python:3.7.9
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
COPY requirements.txt /requirements.txt
RUN pip install --upgrade pip -r /requirements.txt && mkdir /code 
WORKDIR /code
COPY . /code/
RUN apt update && apt-get update && apt install tesseract-ocr -y && apt-get install ffmpeg libsm6 libxext6  -y
CMD ["python", "/code/watcher.py"]

我的解析器Dockerfile:

FROM python:3.7.9
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
COPY requirements.txt /requirements.txt
RUN pip install --upgrade pip -r /requirements.txt && mkdir /code
WORKDIR /code
COPY . /code/
RUN apt update && apt-get update && apt-get install ffmpeg -y
CMD ["python", "/code/parser.py"]

My requirements.txt:

Pillow == 5.4.1
gql == 3.0.0a5
matplotlib == 3.0.3
numpy == 1.16.2
opencv_python == 4.4.0.44
pandas == 0.24.2
pytesseract == 0.2.6
python_ffmpeg_video_streaming == 0.1.14
watchdog == 2.0.2
requests
tesseract

任何帮助都将不胜感激


Tags: pathdockerfromimportselfsrceventos
1条回答
网友
1楼 · 发布于 2024-04-25 05:13:23

watchdog用来监视linux文件系统事件的底层API称为inotify。委员会注意到:

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

您正在装载的目录c:\My_MR位于Windows文件系统上,因此watcher容器中的inotify不起作用

相反,您可以使用linux文件系统路径从WSL2默认发行版中的运行docker,例如~/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 

当WSL2发行版使用\\wsl$\网络路径运行时,可以从Windows访问此目录,即\\wsl$\<Distro name>\home\<username>\my_mr(更多信息here)。因此,我相信docker run也可以从Windows使用带有-v\\wsl$\路径

相关问题 更多 >