📝

ローカルフォルダを監視して S3 と同期するアプリケーションを作ってみた

に公開

AWS SDK の入門レベルとして作ってみました。

前提

  • 開発環境: Cloud9 を作成済み

1. S3 バケットの作成

デフォルト設定で S3 バケットを作成しました。

2. Cloud9 環境の設定

アプリ作成に必要な設定を行います。
まずはターミナルで以下のコマンドを実行します。

$ pip install boto3 watchdog
$ mkdir s3-sync-app
$ cd s3-sync-app
$ mkdir watch_folder

watch_folder を監視対象のフォルダとして使用します。

3. アプリの作成

s3-sync-app フォルダ内に app.py というファイルを作成して以下のコードを貼り付けます。
BUCKET_NAME の値である your-bucket-name は手順 1 で作成した S3 バケット名に置換します。

app.py
import boto3
import os
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# S3クライアントの作成
s3 = boto3.client('s3')

# 設定(バケット名を変更してください)
BUCKET_NAME = 'your-bucket-name'
WATCH_FOLDER = './watch_folder'

class S3SyncHandler(FileSystemEventHandler):
    
    def on_created(self, event):
        if not event.is_directory:
            self.upload_to_s3(event.src_path)
    
    def on_modified(self, event):
        if not event.is_directory:
            self.upload_to_s3(event.src_path)
    
    def on_deleted(self, event):
        if not event.is_directory:
            self.delete_from_s3(event.src_path)
    
    def upload_to_s3(self, file_path):
        try:
              s3_key = os.path.relpath(file_path, WATCH_FOLDER)
            s3.upload_file(file_path, BUCKET_NAME, s3_key)
            print("アップロード成功")
        except Exception as e:
            print(e)
    
    def delete_from_s3(self, file_path):
        try:
            s3_key = os.path.relpath(file_path, WATCH_FOLDER)
            s3.delete_object(Bucket=BUCKET_NAME, Key=s3_key)
            print("削除成功")
        except Exception as e:
            print(e)

def main():
    
    # 既存ファイルを初回同期
    for root, dirs, files in os.walk(WATCH_FOLDER):
        for file in files:
            file_path = os.path.join(root, file)
            handler = S3SyncHandler()
            handler.upload_to_s3(file_path)
    
    # フォルダ監視開始
    event_handler = S3SyncHandler()
    observer = Observer()
    observer.schedule(event_handler, WATCH_FOLDER, recursive=True)
    observer.start()
    
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    
    observer.join()

if __name__ == "__main__":
    main()

4. 動作確認

アプリを起動する前に watch_folder 内に適当なファイルを作成して初回同期の動作を確認します。
今回は sample.txt を作成しました。
以下のコマンドでアプリを実行します。

$ python3 app.py

アプリ実行後、watch_folder 内 のファイルが S3 バケットにアップロードされていれば初回同期完了です。

アプリを起動したままの状態で、watch_folder 内にファイルを追加してみます。

$ echo "Hello World" > ./watch_folder/new.txt

new.txt も S3 バケットにアップロードされました。

次は nex.txt を削除します。

$ rm ./watch_folder/new.txt

new.txt が S3 バケットから削除されました。

最後にファイルの更新もやってみます。

$ echo "新しい内容です" > ./watch_folder/sample.txt

S3 バケットにアップロードされた sample.txt に「新しい内容です」と記載されていれば OK です。

まとめ

今回はローカルフォルダを監視して S3 と同期するアプリケーションを作ってみました。
どなたかの参考になれば幸いです。

Discussion