SFTPサーバにファイルを 〜ファイルをPUT〜

記事タイトルとURLをコピーする

年がら年中、レモンを大量に消費してるので、業務用のレモンと炭酸水で、レモンスカッシュを飲んでいる技術課の森です。

はじめに

前回作成したSFTPサーバに対して、これからプログラムを作成して、実際にファイルをPUT/GETしていきます。

前回のブログは こちら

今回は ローカルで作成したプログラムでSFTPサーバにファイルをPUT します。

プログラム

環境/ライブラリ

まずは環境やライブラリについてです。

  • virtualenv(20.0.16)
  • python(3.7.3)
  • paramiko(2.7.1)(Pythonで使うライブラリ)

これを利用してプログラムを作成していきます。 なお、プログラムは異常処理など行っていないので、 利用される際は、適宜異常処理を行ってください。

プログラム

今回は単純にプログラム実行ディレクトリ直下にPUTするファイルを配置しておき、 そのファイルをSFTPサーバに配置するプログラムです。 特定のディレクトリにあるファイルを再帰的にアップロードする場合は、 glob を使えば実現可能です。

ファイル名を sftp_put.py とします。

import paramiko

# 定数定義
## 接続先のSFTPサーバのIPアドレス
HOSTNAME = "xx.xx.xx.xx"
## 接続先のSFTPサーバのポート番号
PORT = 22
## 接続先のSFTPサーバの接続ユーザ名
USERNAME = "sftp-user"
## 接続先のSFTPサーバの接続ユーザ用の秘密鍵
PRIVATE_KEY = 'id_rsa'
## 接続先のSFTPサーバでファイルのPUT/GETできるディレクトリ名
SFTP_DIR = "sftp-work-dir/"

# 接続準備
## SSH接続の準備
transport = paramiko.Transport((HOSTNAME, PORT))
## 秘密鍵の設定
### http://docs.paramiko.org/en/stable/api/keys.html#paramiko.pkey.PKey.from_private_key_file
rsa_private_key = paramiko.RSAKey.from_private_key_file(PRIVATE_KEY)
## SSHで接続
transport.connect(username=USERNAME, pkey= rsa_private_key)

# ファイル指定
## PUTするファイルを設定
path = './putfile'

# SFTPでPUT
## SFTPクライアント生成
sftp = paramiko.SFTPClient.from_transport(transport)
## SFTPでファイルをPUT
sftp.put(path, SFTP_DIR + path)
## SFTPをクローズ
sftp.close()
## SSHをクローズ
transport.close()

プログラムの実行

では、プログラムを実行していきます。 秘密鍵( id_rsa )をプログラムの実行ディレクトリに配置します。 その後、PUTするファイル( putfile )を同じく、プログラムの実行ディレクトリに配置します。

$ python sftp_put.py

実行後の確認

では、SFTPサーバにログインして、ファイルが配置されたかを確認します。

$ ls -l putfile 
-rw-r--r--  1 localuser  staff  47  5  7 14:40 putfile
$ sftp -i id_rsa sftp-user@[EC2のIPv4パブリックIP]
sftp> cd sftp-work-dir
sftp> ls -la
drwxrwxrwx    2 1001     1001           36 May  7 08:04 .
drwxr-xr-x    3 0        0              18 May  7 07:24 ..
-rw-r--r--    1 1001     1001           47 May  7 07:16 putfile
sftp> 

ちゃんと同じファイルがPUTされてますね。 これで作業は完了です。

さいごに

これで、SFTPサーバを構築した後に、PythonスクリプトでファイルをPUTするところまでできました。 次は、ファイルをGETするプログラムです。

プログラム的には、1ファイルをPUTする仕組みでしたのでそれほど難しいものではなかったのですが、再帰的にファイルを送る場合は、「ファイル指定」から下を置き換えることで対応が可能です。 サンプルではありますが、抜粋して記載します。

# 再帰的にPUTするファイルがあるディレクトリに移動
os.chdir("/tmp/files")
# すべてのファイルを対象にする
# 拡張子が「txt」の場合は「./*.txt」、「jpg」の場合は「./*.jgp」にする
files_path = "./*"
files = glob.blog(files_path)

# SFTPでPUT
## SFTPクライアント生成
sftp = paramiko.SFTPClient.from_transport(transport)

# ファイルの数だけループ
for i in files:
    if os.path.isfile(i):
        sftp.put(i, SFTP_DIR + i)

では、次回のSFTPサーバにファイルをGETするでお会いしましょう。