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?
You can create directory/folder in remote server programmatically by the SFTP. Syntax: psftp> mkdir 'Directory name'
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With