Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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_path not exist):     create_path(remote_path) upload_file(local_file, remote_path) 

I was thinking about executing a command in Paramiko to create the path (e.g. mkdir -p remote_path). I came up with this:

# I didn't test this code  import paramiko, sys  ssh = paramiko.SSHClient() ssh.connect(myhost, 22, myusername, mypassword) ssh.exec_command('mkdir -p ' + remote_path) ssh.close  transport = paramiko.Transport((myhost, 22)) transport.connect(username = myusername, password = mypassword)  sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(local_path, remote_path) sftp.close()  transport.close() 

But this solution doesn't sound good to me, because I close the connection and then reopen it again. Is there a better way to do it?

like image 808
franzlorenzon Avatar asked Feb 11 '13 19:02

franzlorenzon


People also ask

Can SFTP create directory?

You can create directory/folder in remote server programmatically by the SFTP. Syntax: psftp> mkdir 'Directory name'

How do I transfer files using SFTP in Python?

To run the file transferring program over a secure shell, you need to use the pysftp module in your Python program. This module is wrapped around paramiko and utilizes pycrypto libraries to perform the secure transferring of data. Pysftp is easy to implement.


1 Answers

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 exists except 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  def mkdir_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('/')         return     if remote_directory == '':         # top-level relative directory must exist         return     try:         sftp.chdir(remote_directory) # sub-directory exists     except 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)         return True  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.

like image 184
isedev Avatar answered Sep 16 '22 21:09

isedev