Skip to content Skip to sidebar Skip to footer

Upload Files Using Sftp In Python, But Create Directories If Path Doesn't Exist

I want to upload a file on a remote server with Python. I'd like to check beforehand if the remote path is really existing, and if it isn't, to create it. In pseudocode: if(remote_

Solution 1:

SFTP supports the usual FTP commands (chdir, mkdir, etc...), so use those:

sftp = paramiko.SFTPClient.from_transport(transport)
try:
    sftp.chdir(remote_path)  # Test if remote_path existsexcept IOError:
    sftp.mkdir(remote_path)  # Create remote_path
    sftp.chdir(remote_path)
sftp.put(local_path, '.')    # At this point, you are in remote_path in either case
sftp.close()

To fully emulate mkdir -p, you can work through remote_path recursively:

import os.path

defmkdir_p(sftp, remote_directory):
    """Change to this directory, recursively making new folders if needed.
    Returns True if any folders were created."""if remote_directory == '/':
        # absolute path so change directory to root
        sftp.chdir('/')
        returnif remote_directory == '':
        # top-level relative directory must existreturntry:
        sftp.chdir(remote_directory) # sub-directory existsexcept IOError:
        dirname, basename = os.path.split(remote_directory.rstrip('/'))
        mkdir_p(sftp, dirname) # make parent directories
        sftp.mkdir(basename) # sub-directory missing, so created it
        sftp.chdir(basename)
        returnTrue

sftp = paramiko.SFTPClient.from_transport(transport)
mkdir_p(sftp, remote_path) 
sftp.put(local_path, '.')    # At this point, you are in remote_path
sftp.close()

Of course, if remote_path also contains a remote file name, then it needs to be split off, the directory being passed to mkdir_p and the filename used instead of '.' in sftp.put.

Solution 2:

Something simpler and slightly more readable too

defmkdir_p(sftp, remote, is_dir=False):
    """
    emulates mkdir_p if required. 
    sftp - is a valid sftp object
    remote - remote path to create. 
    """
    dirs_ = []
    if is_dir:
        dir_ = remote
    else:
        dir_, basename = os.path.split(remote)
    whilelen(dir_) > 1:
        dirs_.append(dir_)
        dir_, _  = os.path.split(dir_)

    iflen(dir_) == 1andnot dir_.startswith("/"): 
        dirs_.append(dir_) # For a remote path like y/x.txt whilelen(dirs_):
        dir_ = dirs_.pop()
        try:
            sftp.stat(dir_)
        except:
            print"making ... dir",  dir_
            sftp.mkdir(dir_)

Solution 3:

Had to do this today. Here is how I did it.

defmkdir_p(sftp, remote_directory):
    dir_path = str()
    for dir_folder in remote_directory.split("/"):
        if dir_folder == "":
            continue
        dir_path += r"/{0}".format(dir_folder)
        try:
            sftp.listdir(dir_path)
        except IOError:
            sftp.mkdir(dir_path)

Solution 4:

you can use pysftp package:

import pysftp as sftp

#used to pypass key login
cnopts = sftp.CnOpts()
cnopts.hostkeys = None

srv = sftp.Connection(host="10.2.2.2",username="ritesh",password="ritesh",cnopts=cnopts)
srv.makedirs("a3/a2/a1", mode=777)  # will happily make all non-existing directories

you can check this link for more details: https://pysftp.readthedocs.io/en/release_0.2.9/cookbook.html#pysftp-connection-mkdir

Solution 5:

Paramiko contains a mkdir function:

http://paramiko-docs.readthedocs.org/en/latest/api/sftp.html#paramiko.sftp_si.SFTPServerInterface.mkdir

Post a Comment for "Upload Files Using Sftp In Python, But Create Directories If Path Doesn't Exist"