用Python操作SFTP的簡易程式碼

wait4friend發表於2018-05-20

因為一個具體專案的需求,我們需要在SFTP環境下上傳下載資料。以前類似的需求是在Windows環境下用CMD呼叫WinSCP實現的,現在需要使用Pthon,就學習了一下paramiko庫的簡單使用。

記錄一下已經實現的部分:

  1. 安裝paramiko庫
  2. 單檔案的上傳和下載
  3. 多檔案和目錄部分暫時沒有實現,以後需要的時候再補充

安裝paramiko

因為我們使用的是Anaconda環境,所以安裝模組非常簡單

conda install paramiko
複製程式碼

Python程式碼

paramiko的使用方法比較直觀,可以和操作JDBC進行類比。首先獲取一個連結,然後使用這個連結物件進行具體的上傳下載,最後關閉連線。簡單粗暴,非常有效。

獲取Connect

import paramiko
import os

# 獲取連線
def getConnect(host, port, username, password):
    """
    :param host: SFTP ip
    :param port: SFTP port
    :param username: SFTP userName
    :param password: SFTP password
    :return: sftp
    """
    print("SFTP connection...")
    result = [1, ""]
    sftp = None
    
    try:
        handle = paramiko.Transport((host, port))
        handle.connect(username=username, password=password)
        sftp = paramiko.SFTPClient.from_transport(handle)
        print("connection success")
    except Exception as e:
        sftp = None
        print("connection fail, reason:{0}".format(e))

    return sftp
複製程式碼

upload

這裡只實現了簡單的使用,把指定的一個檔案上傳到遠端資料夾,如果資料夾不存在就會首先建立對應的資料夾。

# 上傳指定檔案
def uploadFile(sftp, remoteDir, localPath):
    """
    :param sftp:
    :param remoteDir: 服務端資料夾路徑
    :param localPath: 客戶端檔案路徑
    :return:
    """
    print("start upload file by use SFTP...")
    result = [1, ""]

    try:
        # 是否需要建立目錄
        try:
            sftp.chdir(remoteDir)
        except:
            sftp.mkdir(remoteDir)
            
        fileName = os.path.basename(localPath)
        remotePath = '{0}{1}'.format(remoteDir, fileName)
        sftp.put(localPath, remotePath)   

        result = [1, "upload " + fileName + " success"]
    except Exception as e:
        result = [-1, "upload fail, reason:{0}".format(e)]

    print(result[1])    
    return result
複製程式碼

download

同樣是簡單使用,把伺服器上的一個檔案下載到本地資料夾中。

# 下載檔案  
def downloadFile(sftp, remotePath, localAbsDir):  
    """ 
    :param handle: 
    :param remotePath: 服務端檔案路徑 
    :param localAbsDir: 客戶端資料夾的路徑
    :return: 
    """  
    print("start download file by use SFTP...")  
    result = [1, ""]  
  
    try:   
        fileName = os.path.basename(remotePath)  
        localAbsPath = '{0}{1}'.format(localAbsDir, fileName)  

        lad = os.path.split(localAbsPath)[0]  

        if not os.path.exists(lad):  
            os.makedirs(lad)  

        sftp.get(remotePath, localAbsPath)  

        result = [1, "download " + localAbsPath + " success"]  

    except Exception as e:  
        result = [-1, "download fail, reason:{0}".format(e)]  
    
    print(result[1])
    return result  
複製程式碼

測試程式碼

if __name__ == "__main__":
    sftp = getConnect(  
        host='192.168.1.57',  
        port=22, 
        username='user', 
        password='123456'
    )  

    uploadFile(sftp, '/home/etl/upload/dl_zhihui/out_01/', './sample_upload.txt')
    downloadFile(sftp, '/home/etl/upload/dl_zhihui/cfg_01/sample_download.txt', './')
    
    sftp.close()

複製程式碼
SFTP connection...
connection success
start download file by use SFTP...
download ./sample_download.txt success
複製程式碼

相關文章