Phát hiện thay đổi trong tệp python

Trong blog này, chúng tôi sẽ xây dựng từ đầu cái được gọi là 'Trình theo dõi tệp'. Trình theo dõi tệp là một quá trình theo dõi một thư mục cụ thể để biết sự xuất hiện của bất kỳ tệp nào. Trình theo dõi tệp, khi có bất kỳ tệp nào, sẽ kích hoạt quy trình theo dõi

Ví dụ, hãy tưởng tượng rằng một quy trình hàng ngày yêu cầu phải có tệp từ bộ phận khác. Trừ khi có sẵn trình theo dõi tệp, ai đó sẽ cần theo dõi thủ công sự xuất hiện của tệp đã nói trước khi khởi động quy trình hàng ngày có liên quan theo cách thủ công

Nói chung, trình theo dõi tệp cung cấp chức năng để tạo, sửa đổi, xóa, tồn tại và đổi tên tệp. Họ cũng thường làm điều đó thông qua Sự kiện hệ điều hành bản địa. Tuy nhiên, những thứ này thường không thể hỗ trợ Bộ nhớ dùng chung

Đối với mục đích của chúng tôi, chúng tôi sẽ xây dựng một thứ gì đó rất đơn giản, hoạt động trong mọi trường hợp, chỉ bao gồm trường hợp sử dụng Tệp mới đến

Các nguyên tắc cơ bản

Cuối cùng, xây dựng một trình xem tệp đơn giản là một quá trình rất đơn giản. Thay vì đăng ký các sự kiện hệ điều hành gốc, chúng tôi sẽ thăm dò một thư mục để thay đổi. Toàn bộ điều có thể được giải quyết trong ba chức năng đơn giản

  1. Một hàm trả về danh sách các tệp được tìm thấy trong một thư mục
  2. Một chức năng làm nổi bật sự khác biệt giữa hai danh sách
  3. Một chức năng tiếp tục thăm dò ý kiến

Không có bất kỳ khó khăn nào nữa, hãy đề cập đến ba chức năng

Tập tin trong một thư mục

Điều đầu tiên cần làm là xây dựng một hàm trả về tất cả các tệp trong một thư mục

Chạy chức năng này, trả về một danh sách các tệp, như vậy

Trả về danh sách các tệp được tìm thấy trong một thư mục được chỉ định trước

Sự khác biệt giữa hai danh sách

Tiếp theo, chúng tôi muốn có thể so sánh hai danh sách và trả về sự khác biệt. Bằng cách này, chúng tôi có thể so sánh các danh sách giữa các cuộc bỏ phiếu để chúng tôi có thể xác định xem có tệp mới nào xuất hiện không

Đây là một ví dụ về giao diện của nó

So sánh hai danh sách và trả về sự khác biệt

Kiểm tra định kỳ cho sự khác biệt

Cuối cùng, chúng ta cần một chức năng bỏ phiếu để liên kết toàn bộ lại với nhau. Một vòng lặp vô hạn, với một bộ đếm thời gian ngủ, có thể xử lý nó

Do đó, chúng tôi tạo một vòng lặp vô hạn [trong khi True] và trong mỗi vòng lặp, chúng tôi chụp nhanh các tệp hiện có và so sánh chúng với vòng lặp trước đó để xác định xem có tệp mới nào xuất hiện không

Hàm có hai đầu vào

  1. my_dir. Thư mục để theo dõi
  2. thăm dò ý kiếnThời gian. lượng thời gian [giây] giữa các lần kiểm tra thay đổi

Bằng cách sử dụng chức năng listComparison trước đây của chúng tôi, chúng tôi có thể theo dõi khi các tệp mới xuất hiện, tại thời điểm đó, chúng tôi có thể gọi một chức năng mới doThingsWithNewFiles, chuyển danh sách các tệp mới để thực hiện điều gì đó với

Bạn đã biết rồi đấy, trong chưa đầy 50 dòng mã, chúng tôi đã viết mã FileWatcher có thể đọc được của riêng mình

Máy tính xách tay Jupyter

Dưới đây tôi đang tổng hợp mọi thứ lại với nhau trong Sổ ghi chép Jupyter mà bạn có thể sử dụng trong các dự án của riêng mình

suy nghĩ cuối cùng

Tôi hy vọng bạn thấy điều này hữu ích và nó giúp với một số trường hợp sử dụng đơn giản. Bạn có suy nghĩ hoặc ý tưởng về cách mở rộng và xây dựng dựa trên nó không?

Hãy tưởng tượng bạn làm việc với hệ thống máy khách nơi họ tải tệp lên thư mục FTP. Chúng tôi phải xử lý tệp ngay khi nó xuất hiện trong thư mục và đẩy tệp vào cơ sở dữ liệu.  

Bảng điều khiển thời gian thực đang truy cập cơ sở dữ liệu. Do đó, chúng tôi phải cập nhật cơ sở dữ liệu ngay lập tức.  

Có liên quan. Cách tôi tạo Bảng điều khiển rực rỡ hoàn toàn bằng Python

Bạn có thể chạy một tác vụ định kỳ và kiểm tra nội dung thư mục. Nhưng giả sử bạn cập nhật cơ sở dữ liệu càng nhanh thì càng tốt cho người dùng. Chi phí của độ trễ nhỏ khi sử dụng tác vụ định kỳ cao. Khoảng thời gian ngắn hơn có thể cần nhiều tài nguyên hơn vì nhiệm vụ của bạn chạy thường xuyên hơn.  

Liên kết được Tài trợ

Chúng ta cần xây dựng trình kích hoạt hệ thống tệp để hoàn thành nhiệm vụ.  

Theo dõi quá trình tạo tệp mới trong một thư mục.  

Chúng ta có thể sử dụng tập lệnh Python tích cực lắng nghe các sự kiện hệ thống tệp trong một thư mục.  

Chúng ta có thể bắt đầu bằng cách cài đặt gói Python có tên là Watchdog. Nó có sẵn thông qua kho lưu trữ PyPI.  

pip install watchdog
# If you're using Poetry instead of Virtualenv
poetry add watchdog.

Đây là một ví dụ để bắt đầu với. Tập lệnh Python sau sẽ theo dõi các thay đổi của tệp trong thư mục hiện tại. Nó sẽ ghi lại tất cả các thay đổi khi chúng xảy ra.  

Liên kết được Tài trợ
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


class FileCreateHandler[FileSystemEventHandler]:
    def on_created[self, event]:
        print["Created: " + event.src_path]

if __name__ == "__main__":

    event_handler = FileCreateHandler[]

    # Create an observer.
    observer = Observer[]

    # Attach the observer to the event handler.
    observer.schedule[event_handler, ".", recursive=True]

    # Start the observer.
    observer.start[]

    try:
        while observer.is_alive[]:
            observer.join[1]
    finally:
        observer.stop[]
        observer.join[]

Phần quan trọng của đoạn mã trên là lớp FileProcessor. Nhưng trước khi vào đó, chúng ta nên tạo một đối tượng quan sát viên để đính kèm một trình xử lý sự kiện.  

Liên kết được Tài trợ

Chúng ta có thể đính kèm một trình xử lý sự kiện cho người quan sát bằng cách sử dụng phương thức lịch biểu. Trong ví dụ trên, chúng tôi đã đính kèm nó để xem các sự kiện trong thư mục hiện tại và tất cả các thư mục xuôi dòng của nó.  

Nếu bạn chạy mã này và tạo một tệp mới trong thư mục hiện tại, chúng ta có thể thấy tập lệnh Python in sự kiện trên thiết bị đầu cuối.  

Chúng tôi đã sử dụng thư mục hiện tại trong phương thức schedule của đối tượng người quan sát. Bạn cũng có thể sử dụng bất kỳ con đường nào bạn chọn. Bạn cũng có thể chọn lấy nó từ đối số dòng lệnh.  

Có liên quan. Làm cách nào để thực thi các lệnh Shell với Python?

Đây là một sửa đổi đối với cùng mã chuyển đổi tập lệnh của chúng tôi thành CLI. Bây giờ bạn có thể chuyển đường dẫn tới màn hình bằng đối số dòng lệnh.  

...
import argparse

...


if __name__ == "__main__":
    parser = argparse.ArgumentParser[
        description="Watchdog script to watch for new CSV files and load them into the database"
    ]
    parser.add_argument["path", help="Path to watch for new CSV files"]

    args = parser.parse_args[]
    path = args.path

    # Create an observer.
    observer = Observer[]

    observer.schedule[event_handler, path, recursive=True]
    
    ...

Bây giờ bạn có thể chạy tập lệnh của mình như sau trong thiết bị đầu cuối của mình

Liên kết được Tài trợ

python .py /somewhare/in/your/computer

Trong bài viết trước của tôi, bạn có thể tìm hiểu thêm về cách tạo giao diện dòng lệnh bằng Python

Xử lý các thay đổi đối với tệp trong lớp trình xử lý

Trong ví dụ của chúng tôi, chúng tôi đã tạo một trình xử lý sự kiện bằng cách phân lớp con lớp 'FileSystemEventHandler'. Tất cả các trình xử lý sự kiện phải như thế này.  

Lớp cha có trình giữ chỗ cho một số phương thức cho các sự kiện hệ thống tệp. Chúng tôi đã sử dụng phương thức 'on_create' để xử lý tất cả các tệp mới được tạo. Tương tự như vậy, bạn cũng có thể sử dụng các phương thức on_deleted, on_modified, on_moved và on_any_event để xử lý các loại sự kiện khác.  

Hãy cập nhật on_create để xử lý tệp và chèn giá trị vào cơ sở dữ liệu. Vui lòng bỏ qua phần này nếu nó không liên quan đến trường hợp sử dụng của bạn.  

import os

import pandas as pd
from sqlalchemy import create_engine
from watchdog.events import FileSystemEventHandler
...


class FileCreateHandler[FileSystemEventHandler]:
    def on_created[self, event]:
        # Create SQLAlchemy engine for postgres database using environment variables
        engine = create_engine[os.environ["DATABASE_URL"]]
        
        with engine.connect[] as con:
            # Read the CSV data
            df = pd.read_csv[event.src_path]

            # Do the required transformations
            df["date"] = pd.to_datetime[df["date"]]

            # Write the data to the database
            df.to_sql["weather", con, if_exists="append", index=False]
            
...

Mã này có thể trông rất quen thuộc nếu bạn đã làm việc với Sqlalchemy và Pandas. Điều đáng chú ý là cách chúng ta lấy đường dẫn của tệp mới tạo.  

Mỗi trình kích hoạt sự kiện trong lớp 'FileSystemEventHandler' tham chiếu đường dẫn trong đối số sự kiện của nó. Chúng tôi có thể truy cập nó bằng thẻ src-path như trong mã.  

Liên kết được Tài trợ

Nếu bạn chạy mã và để tập lệnh Python lắng nghe các thay đổi, nó cũng sẽ ngay lập tức đẩy các thay đổi đó vào cơ sở dữ liệu.  

Phục vụ ứng dụng của bạn trong nền

Đến bây giờ, bạn đã nhận thấy rằng ứng dụng của chúng tôi chạy trên thiết bị đầu cuối trực tiếp. Nhưng nó không phải là khôn ngoan để làm điều này trong sản xuất. Bất cứ điều gì đối với phiên cuối có thể ảnh hưởng đến ứng dụng.  

Cách tốt nhất để chạy các dịch vụ đó trong nền là thông qua một dịch vụ hệ thống. Người dùng Windows có thể sử dụng công cụ NSSM [Non-sucking Service Manager. ] Sẽ khá đơn giản nếu bạn lướt qua tài liệu của họ.  

Nhưng trong bài đăng này, tôi sẽ đề cập đến việc sử dụng systemctl của hệ thống Linux.  

Bạn có thể tạo một dịch vụ hệ thống mới bằng cách tạo một tệp có nội dung sau trong thư mục '/etc/systemd/system'. Bạn có thể đặt tên cho nó bất cứ thứ gì với phần mở rộng là '. Dịch vụ'

[Unit]
Description="Process Data"

[Service]
Restart=always
WorkingDirectory=
ExecStart= .py

[Install]
WantedBy=multi-user target

Sau khi hoàn tất, bạn có thể chạy các lệnh sau trên thiết bị đầu cuối để kích hoạt dịch vụ.  

# To make your new service available to systemctl utility.
$ systemctl daemon-reload

# To start the service 
$ systemctl start .service

Điều này sẽ bắt đầu quá trình. Bây giờ, khi các tệp mới đang được tạo trên đích FTP của chúng tôi, dịch vụ này sẽ xử lý và tải chúng lên cơ sở dữ liệu. Và cơ sở dữ liệu thời gian thực của chúng tôi sẽ nhận được dữ liệu mới mà không có bất kỳ sự chậm trễ nào.  

Bạn có thể kiểm tra xem dịch vụ của mình có chạy đúng không bằng lệnh sau.  

systemctl status .service

suy nghĩ cuối cùng

Ngày nay, việc xử lý thay đổi hệ thống tệp rất hiếm khi thế giới hướng tới sự tích hợp mạnh mẽ hơn giữa các hệ thống. Nhưng điều đó không có nghĩa là trình kích hoạt hệ thống tập tin không có cách sử dụng.  

Liên kết được Tài trợ

Có nhiều trường hợp chúng ta cần theo dõi việc tạo hoặc sửa đổi tệp mới. Lấy ví dụ, xử lý luồng nhật ký. Bạn có thể sử dụng kỹ thuật được mô tả ở đây để xử lý một dòng nhật ký mới và đẩy nó vào kho dữ liệu.  

Tôi đã sử dụng nó trong một thời gian dài. Và tôi không thấy cần phải giảm bớt.  

Bạn có thích những gì bạn đọc?

Làm thế nào để Python biết các thay đổi đối với một thư mục?

Watchdog là gói Python tiện dụng sử dụng hệ thống con inotify nhân Linux để theo dõi mọi thay đổi đối với hệ thống tệp . Điều này làm cho nó trở thành một nền tảng tuyệt vời để xây dựng một tập lệnh nhỏ thực hiện hành động bất cứ khi nào một tệp được nhận trong một thư mục hoặc bất kỳ nội dung nào của thư mục thay đổi.

Trình theo dõi tệp là gì?

Trình theo dõi tệp là công cụ IntelliJ IDEA cho phép bạn tự động chạy công cụ dòng lệnh như trình biên dịch, trình định dạng hoặc linters khi bạn thay đổi hoặc lưu tệp trong IDE< . .

Chủ Đề