[Python] SFTPを利用して指定ディレクトリの最新ファイルをダウンロードする
はじめに
以前、PythonでFTPを利用して、指定ディレクトリの最新ファイルをダウンロードする処理についてまとめました。
今回は、Pythonで、SFTPを利用して、指定ディレクトリの最新ファイルをダウンロードする処理を実装していきます。
SFTPとは
FTPとSFTPの違いについて、下記の説明が非常にわかりやすかったです。
https://wa3.i-3-i.info/diff679ftp.html
使用するライブラリ
Paramiko
SSHを操作するためのライブラリ。使用時にはインストールが必要です。
datetime
日付、時刻を扱うライブラリ。標準ライブラリのため、インストール不要で使用可能です。
動作環境
windows11
Jupyter Notebook 6.5.2(Python 3.10.9)
実装
全体コードは下記です。
import paramiko
from datetime import datetime
hostname = 'ホスト名'
username = 'ユーザー名'
password = 'パスワード'
directory = '/xxx/xxxxxxx/'
# SSHクライアントの作成
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
# SFTPセッション開始
sftp_connection = client.open_sftp()
# ファイル一覧取得
files_info = sftp_connection.listdir(directory)
file_list = []
for file_name in files_info:
file_path = directory + '/' + file_name
# ファイル情報を取得
file_stat = sftp_connection.stat(file_path)
modify_dt = datetime.fromtimestamp(file_stat.st_mtime)
file_list.append({'file_name': file_name, 'modify_time': modify_dt})
# ファイル更新日が最新のファイルを取得
latest_file_info = max(file_list, key = lambda x:x['modify_time'])
# ファイル取得
sftp_connection.get(directory + '/' + latest_file_info['file_name'], latest_file_info['file_name'])
finally:
# SFTPセッションの終了
sftp_connection.close()
# SSHクライアントの終了
client.close()
コードの詳細について、順番に説明していきます。
SSHクライアントの作成、接続
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname, username=username, password=password)
SFTP接続をする際、Paramikoライブラリを使用して、SSHクライアントのインスタンスを生成します。
その後、SSHサーバーと接続をします。
connectメソッドで失敗する場合、例外を送出するため、try文を使用しています。
SFTPセッション開始
sftp_connection = client.open_sftp()
SFTPセッションを開始するopen_sftpメソッドを実行します。
戻り値は、SFTPClientクラスとなります。
指定ディレクトリのファイル一覧を取得
files_info = sftp_connection.listdir(directory)
指定ディレクトリ配下にあるファイル一覧を取得するには、listdirメソッドを使用します。
第1引数で、対象のディレクトリのパスを設定します。
各ファイルのファイル情報より更新日時を取得
file_list = []
for file_name in files_info:
file_path = directory + '/' + file_name
# ファイル情報を取得
file_stat = sftp_connection.stat(file_path)
modify_dt = datetime.fromtimestamp(file_stat.st_mtime)
file_list.append({'file_name': file_name, 'modify_time': modify_dt})
listdirメソッドで取得したファイル名のリストをfor文でループして、すべてのファイル名を1つずつ取り出しています。
ファイル情報を取得するには、statメソッドを使用します。statメソッドの戻り値は、標準ライブラリのosライブラリで提供されているstatモジュールと同じ構造のデータが取得できます。
statメソッドの戻り値SFTPAttributesから、更新日時のタイムスタンプである、st_mtimeを取得します。
取得した更新日時のタイムスタンプst_mtimeを、datetimeライブラリのfromtimestampメソッドを使用して、datetimeオブジェクトに変換します。
取得したファイル名と更新日時をペアとした辞書型として、リストに格納していきます。
各ファイルのファイル情報より更新日時を取得
# ファイル更新日が最新のファイルを取得
latest_file_info = max(file_list, key = lambda x:x['modify_time'])
ファイル名と更新日時がペアになっている辞書型のリストより、日付が最新のリストを取得するため、max関数を使用します。
lambda関数で、更新日時のキーであるmodify_timeを指定しています。
指定ファイルをダウンロード
# ファイル取得
sftp_connection.get(directory + '/' + latest_file_info['file_name'], latest_file_info['file_name'])
ファイルの取得は、getメソッドを使用します。
第1引数には、ダウンロード元のパス、第2引数にはダウンロード先のパスを指定します。
今回は、カレントディレクトリにダウンロードしてくるので、第2引数では、ファイル名のみ指定しています。
SFTPセッション、SSHクライアントの終了
# SFTPセッションの終了
sftp_connection.close()
# SSHクライアントの終了
client.close()
try文のfinally節で、終了処理としてSFTPセッション、SSHクライアントの終了を実行しています。
まとめ
今回は、Pythonで、SFTPを利用して指定ディレクトリの最新ファイルをダウンロードする処理を実装しました。