この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部のueharaです。
今回はdockerイメージからSFTPサーバーを作成し、Pythonで一時ファイルの作成・ファイルのアップロードを行うという検証をしてみたいと思います。
SFTPじゃなくてFTPが知りたい!って方は以下の記事をご参考下さい。
dockerによるSFTPサーバーの構築
SFTPのdockerイメージは atmoz/sftp を利用したいと思います。
dockerイメージのダウンロード
以下のコマンドを実行し、イメージのダウンロードを行います。
docker pull atmoz/sftp
コンテナの起動
イメージの用意ができたら、 docker-compose.yml
ファイルを作成します。
docker-compose.yml
version: '3'
services:
sftp:
image: atmoz/sftp
container_name: sftp-test
# docker-compose.ymlがあるディレクトリに、コンテナとの共有ディレクトリを作る
volumes:
- ./data:/home/testuser/data
ports:
- "2222:22"
command: testuser:test123:::data
今回はあくまでローカル環境での検証を目的としているため、ユーザー名は testuser
、パスワードは test123
としています。
コンテナ側の22番ポートには、ホスト側の 2222
番を割り当てます。
コンテナとの共有ディレクトリについても、 docker-compose.yml
を置くディレクトリと同じ階層としています。
docker-compose.yml
の準備が完了したら、 docker-compose.yml
があるディレクトリでdocker-compose upを実行し、コンテナを起動します。
docker-compose up
コンテナを起動すると、ホスト側に共有ディレクトリが作成され、以下のようになっているかと思います。
.
├ data
└ docker-compose.yml
以上でSFTPサーバーの構築は完了です。
PythonによるSFTPサーバーへのアクセス
接続先情報の準備
今回、接続先情報は別ファイルで管理し、Pythonの標準モジュールであるconfigparserで読み込む形としたいと思います。
先程 docker-compose.yml
で設定した接続情報を、 config.ini
に書き起こしてみます。
config.ini
[sftp]
host = localhost
port = 2222
username = testuser
password = test123
PythonでのSFTPサーバーへのアクセス
Pythonを利用して、一時ファイルを作成し、それをSFTPでアップロードしてみたいと思います。
全体のコードとしては以下の通りです。
sftp_test.py
import configparser
import tempfile
import paramiko
# config.iniの読み取り
config = configparser.ConfigParser()
config.read("config.ini", encoding="utf-8")
# 接続するためのSSHクライアントの準備
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
# 接続先情報を設定して接続
client.connect(
cofig["sftp"]["host"],
port=int(cofig["sftp"]["port"]),
username=cofig["sftp"]["username"],
password=cofig["sftp"]["password"]
)
# セッション開始
sftp = client.open_sftp()
# 一時ファイルを作成してアップロード
with tempfile.NamedTemporaryFile(mode="w", encoding="utf8") as tmpf:
tmpf.write("This is test file.\n")
tmpf.flush()
sftp.put(tmpf.name, "/data/test.txt")
sftp.close()
client.close()
SFTPのクライアントとしては、 Paramiko を利用しています。
ParamikoのSSH Clientに関してはこちらのドキュメントに記載がありますが、 open_sftp()
でSFTP client objectを取得することができます。
一時ファイルの作成には、Pythonの標準モジュールである tmpfile を利用しています。こちらは、一時ファイルやディレクトリを作成する際に非常に便利なモジュールです。
特に tempfile.NamedTemporaryFile()
は一時ファイルのpathが取得できるのが特徴です。
1つ注意点として、WindowsだとNamedTemporaryFileで一時ファイルを開いている状態で、その名前を使用して再度ファイルを開くことができません(UNIX系のシステムであれば問題なし)。
その場合でも、以下のように記載をすることができます。
with tempfile.NamedTemporaryFile(mode="w", encoding="utf8", delete=False) as tmpf:
tmpf.write("This is test file.\n")
tmpf_name = tmpf.name
sftp.put(tmpf_name, "/data/test.txt")
上記プログラム sftp_test.py
を実行後、ホスト側の共有ディレクトリである data
に、 test.txt
がアップロードされていれば成功です。
.
├ data
└ test.txt
└ docker-compose.yml
test.txt
This is test file.
最後に
今回はdockerイメージからSFTPサーバーを作成し、Pythonで一時ファイルの作成・アップロードを行うといった検証をしてみました。
参考になりましたら幸いです。