Upload folders from Windows to Linux sftp server with Python Paramiko

There is a folder is generated on daily basis, and the folder should be uploaded to a Linux server through sftp protocol on the next day. Instead of manually uploading it every day, we can do it in a script on Task Scheduler or cron job if it's Linux client.

 
# coding=utf-8
import paramiko
import os
 
def sftp_upload(host,port,username,password,local,remote):
    transport = paramiko.Transport((host,port))
    transport.connect(username = username,password = password)
    sftp = paramiko.SFTPClient.from_transport(transport)
    try:
        if os.path.isdir(local):
            for f in os.listdir(local):
                if not os.path.isdir((os.path.join(local+f))):
                    print("uploading:",os.path.join(local+f),os.path.join(remote+f))
                    sftp.put(os.path.join(local+f),os.path.join(remote+f))
                    continue
                print('mkdir: ',os.path.join(remote+f),"returning: ", sftp.mkdir(os.path.join(remote+f)))
                for d in os.listdir(os.path.join(local+f)):
                    if(os.path.isdir(os.path.join(local+f+"\\"+d))):
                        sftp_upload(host,port,username,password,local+f+"\\",remote+f+'/')
                        continue
                    print("uploading:",os.path.join(local+f+"\\"+d),os.path.join(remote+f+'/'+d))
                    sftp.put(os.path.join(local+f+"\\"+d),os.path.join(remote+f+'/'+d))
        else:
            sftp.put(local,remote)
    except Exception as e:
        print('exception:',e)
    transport.close()
 
if __name__ == '__main__':
    sftp_upload('192.168.1.9',22,'user','password','C:\\Program Files (x86)\\Output\\','/home/cms/resource/')
 

For the simplicity purpose, this script will create new sftp connections in each recursive invocation. If you have a lot of sub directories, consider sharing the same connection in all recursive invocations.

If you need to remove the files and directories after uploading, add os.remove on each uploaded file path and at the end of the loop, call os.rmdir on the directory path. The for loop should look like this

 
            for f in os.listdir(local):
                if not os.path.isdir((os.path.join(local+f))):
                    print("uploading:",os.path.join(local+f),os.path.join(remote+f))
                    sftp.put(os.path.join(local+f),os.path.join(remote+f))
                    print("removing file", os.path.join(local+f))
                    os.remove(os.path.join(local+f))
                    continue
                print('mkdir: ',os.path.join(remote+f),"returning: ", sftp.mkdir(os.path.join(remote+f)))
                for d in os.listdir(os.path.join(local+f)):
                    if(os.path.isdir(os.path.join(local+f+"\\"+d))):
                        sftp_upload(host,port,username,password,local+f+"\\",remote+f+'/')
                        continue
                    print("uploading:",os.path.join(local+f+"\\"+d),os.path.join(remote+f+'/'+d))
                    sftp.put(os.path.join(local+f+"\\"+d),os.path.join(remote+f+'/'+d))
                    print("removing file", os.path.join(local+f+"\\"+d))
                    os.remove(os.path.join(local+f+"\\"+d))
                print("removing dir: ", os.path.join(local+f))
                os.rmdir(os.path.join(local+f))