使用Python在目录中进行文件监视,然后在文件修改时使用POST请求发送数据

时间:2019-09-13 07:43:49

标签: python python-3.x python-requests watchdog python-watchdog

我想观看两个不同的目录以进行excel文件修改(时间戳),修改后我想向一个端点调用一个API HTTP Post请求,我已经使用Python Watchdog和请求库编写了以下代码,但是面临两个错误在相同的。

问题1:-event(event.event_type =='modified')在一次文件修改中两次触发,这导致发送两个后数据请求。那么什么是正确的事件类型来监视看门狗库中的文件修改,这将使此条件代码仅一次为true。

问题2:在“ Watcher”类的“启动”函数中,我无法将Handler()值分配给event_handler变量。我在这里犯了什么错误?

请指导我解决此问题或任何其他更好的方法。预先谢谢你

    import time 
from time import sleep
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import json
import requests
import pandas as pd
import os
from collections import defaultdict

class Handler(FileSystemEventHandler):

    def __init__(self, path):
        super().__init__()
        self.path = path   
        self.files = defaultdict(lambda:0)     

    def on_modified(self, event):
        if event.is_directory:
            return None

        elif (event.event_type == 'modified' and event.src_path.endswith('.csv')):
                # api_url = 'http://10.166.72.3:8080/promo/summary?userId=abc'
                stats = os.stat(event.src_path).st_ctime
                sleep(5)
                if stats - self.files[event.src_path] > 1:
                    df = pd.read_csv(self.path)
                    df1 = df.to_json(orient='records')
                    df1.replace("\\","")
                    print(df1)

        self.files[event.src_path] = stats
                #r = requests.post(url=api_url, json=df1)
                #print(r.status_code, r.reason, r.text)


class Watcher:

    def __init__(self, directory, handler):
        self.directory = directory
        self.handler = handler
        self.observer = Observer()

    def start(self):
        #event_handler = Handler()
        self.observer.schedule( self.handler, self.directory, recursive=True)
        self.observer.start()

    def stop(self):
        self.observer.stop()

    def join(self):
        self.observer.join()

if __name__ == '__main__': 

    handler1 = Handler('C:\\Users\\BPM_admin\\Desktop\\OCR_RPA\\FirstOCR\\Diageo\\Output\\InvoiceMasterData.csv')
    handler2 = Handler('C:\\Users\\BPM_admin\\Desktop\\OCR_RPA\\SecondOCR\\Diageo\\Output\\AgreementMasterData.csv')

    w1 = Watcher("C:\\Users\\BPM_admin\\Desktop\\OCR_RPA\\FirstOCR\\Diageo\\Output", handler1) 
    w2 = Watcher("C:\\Users\\BPM_admin\\Desktop\\OCR_RPA\\SecondOCR\\Diageo\\Output", handler2) 

    w1.start() 
    w2.start() 

    try:
       while True:
           time.sleep(5)
    except:
        w1.stop() 
        w2.stop() 
        print("Error")

    w1.join() 
    w2.join() 

2 个答案:

答案 0 :(得分:1)

问题1:“修改”事件触发了两次

出现此问题的原因是,当您保存文件,更改数据,然后更改元数据(最后修改...)时,可能会发生多项操作。如果有很多用户,可能很难根据您的需要和更改的频率进行处理。

首先,您应该通过测试扩展名来限制观看的文件,以避免使用临时文件和所有其他格式。然后,我建议保存文件的最后修改时间,以便能够在两个事件之间进行比较,并仅在延迟超过X秒时才触发API调用。

import os
from collections import defaultdict

class Handler(FileSystemEventHandler):

    def __init__(self):
        super().__init__()
        # this dict will store the filenames and the time
        self.files = defaultdict(lambda:0)

    def on_any_event(self, event):
        if event.is_directory:
            return None

        elif (event.event_type == 'modified' and 
              event.src_path.endswith(('.xls','.xlsx'))) :

            # here we get the last change timestamp 
            stats = os.stat(event.src_path).st_mtime

            # delay of 1 sec minimum between 2 changes
            # self.files[event.src_path] is set to 0 thanks to the defaultdict
            if stats - self.files[event.src_path] > 1: 
                print('api call with ', event.src_path)
                # do what you need

            # then update the time for this file
            self.files[event.src_path] = stats

问题2:传递处理程序参数

实例化Handler()时会出错,因为您在构造函数中创建了一个参数path

class Handler(FileSystemEventHandler):

    def __init__(self, path):
        super().__init__()
        self.path = path        

似乎您没有在Handler中使用它,也许您可​​以删除此参数?否则,只需给出您要处理的路径即可:

def start(self):
    event_handler = Handler(self.directory) # or Handler() if you remove path
    self.observer.schedule(event_handler, self.directory, recursive=True)
    self.observer.start()

答案 1 :(得分:0)

您可以通过以下链接检查文件更改监视程序模块:

https://github.com/NVISO-BE/binsnitch

然后进行您自己的警报反馈。