【Python】Paramikoでディレクトリのファイル一覧を取得する方法
Python で SSHv2 プロトコルを実装するためのライブラリと言えば「Paramiko」が有名。
Paramiko は、主にリモートサーバーへの SSH 接続や SFTP(SSHファイル転送プロトコル)を使用したファイル転送を行うために使用されます。
このライブラリをインポートすれば、リモートコマンドの実行やファイル操作を簡単に行うことが可能なんですよね。
今回は、Paramiko を使って FTP サーバの特定ディレクトリにあるファイル一覧を取得してみます。
Paramiko
Paramiko の詳細な説明や、ライブラリの機能については下記のサイトを参照してください。
SFTP と言っても、パスワード認証だとセキュリティ的にどうかと思うので、SSH の公開鍵認証を使った方法で接続してみます。
FTPサーバ
Docker を利用して、手軽に FTP サーバを立ててしまいましょう。
今回は、「atmoz/sftp」を採用します。
docker-compose の yaml ファイルを書くならこんな感じで。
1sftp-server:
2 image: atmoz/sftp
3 container_name: sftp-server
4 volumes:
5 - ./data/hoge.csv:/home/test/output/hoge.csv
6 - ./data/id_rsa.pub:/home/test/.ssh/keys/id_rsa.pub:ro
7 ports:
8 - "2222:22"
9 command: "test::1001::output"
command の引数は以下のような内容。
username:password:uid:gid:dir
各項目を説明すると、
username: ユーザ名
password: パスワード(パスワード認証の場合)
uid: FTPサーバ側のユーザのUID
gid: FTPサーバ側のユーザのGID
dir: FTPサーバの /home/user 配下に作成されるディレクトリ
上記の yaml の場合は、test ユーザに 1001 の UID を振って「/home/test/output」のディレクトリ作るという指示になります。
SSH の公開鍵認証を使うのでパスワードの項目は空にしています。
もちろん docker-compose を使わなくても、docker コマンドで起動もできます。
シンプルにパスワード認証のものを起動するには、以下のコマンドを実行するだけです。
docker run -p 22:22 -d atmoz/sftp username:password:::dir
サンプルコード
では、この FTP サーバに Paramiko で接続してみましょう。
呼び出し元のスクリプトがこちら。
1from sftp import SftpUtil
2
3private_key = """
4-----BEGIN OPENSSH PRIVATE KEY-----
5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
8-----END OPENSSH PRIVATE KEY-----
9"""
10
11config = {
12 "hostname": "localhost",
13 "port": 2222,
14 "username": "test",
15 "passphrase": "hoge",
16 "directory": "output",
17 "private_key": private_key
18}
19
20util = SftpUtil()
21util.transfer(config)
FTP サーバに接続するためのスクリプトは別ファイルに抜き出します。
(sftp.py というファイル名だと仮定します)
1import io
2import paramiko
3
4def connect_sftp(host, port, username, passphrase, private_key):
5 tp = paramiko.Transport((host, port))
6 pkey = paramiko.RSAKey.from_private_key(io.StringIO(private_key), passphrase)
7 tp.connect(username=username, pkey=pkey)
8 client = paramiko.SFTPClient.from_transport(tp)
9 return client, tp
10
11class SftpUtil:
12 def __init__(self):
13
14 def transfer(self, param):
15 hostname = param['hostname']
16 port = param['port']
17 username = param['username']
18 passphrase = param['passphrase']
19 directory = param['directory']
20 private_key = param['private_key']
21
22 sftp_client, transport = connect_sftp(hostname, port, username, passphrase, private_key)
23
24 remote_files = sftp_client.listdir(directory)
25
26 for r_file in remote_files:
27 print("file={}".format(r_file))
まとめ
Paramiko を使って FTP サーバの特定のディレクトリにあるファイル一覧を取得してみました。
Paramiko で FTP サーバへ接続する方法はいくつかありますが、今回は paramiko.Transport() を採用。
また、秘密鍵はサンプルなのでベタな文字列から読み取るようにしました。
こちらは別ファイルにしておいて、paramiko.RSAKey.from_private_key_file() を使うのが一般的でしょうか。
FTP サーバを使う機会は減りましたが、外部のシステムと連携する場合は今でもよく登場します。
スクリプト言語でサクッとプロトタイプが作れるようになっておきたいですね。