Move files from one directory to another with Paramiko
Question:
I have a script that creates and tmp directory on an SFTP server and then puts files in said /tmp
once the transfer is complete however I need to move the files from /tmp
back one directory to root /
. Use Paramiko how would I move the files from one remote directory to another?
Step guide:
Local files —–> Remote Temporary Dir —-> Remote root Dir
Code below if needed:
#!/usr/bin/python
# --------------------------------------------------------------------
#import libraries
# --------------------------------------------------------------------
import paramiko as PM
import os
import datetime
# --------------------------------------------------------------------
# Global Variables
# --------------------------------------------------------------------
host = 'host IP address'
port = 22
username = 'Username'
password = '*********'
# Variable Paths
localPath = '/shares/MILKLINK/fromML'
remotePath = '/'
logPath = '/shares/MILKLINK/logs/PPcfg02.log'
SRCfiles = '/shares/MILKLINK/Milklink.cpy'
# --------------------------------------------------------------------
# Create LOG FILE
# --------------------------------------------------------------------
log = open(logPath, 'a')
log.write(datetime.datetime.now().isoformat()+'n')
# Creating lockfile
if(os.path.isfile('LockSFTP')):
log.write("LOCK FILE STILL EXISTS!")
quit()
else:
os.system(">LockSFTP")
# --------------------------------------------------------------------
# Remove all files from /formML/
# --------------------------------------------------------------------
fileList = os.listdir(localPath)
for fileName in fileList:
try:
os.remove(localPath+"/"+fileName)
except OSError:
log.write("%s could not be deletedn" % fileName)
# --------------------------------------------------------------------
# Create SFTP CONNECTION
# --------------------------------------------------------------------
log.write("Starting Connection...n")
# SSH connection
ssh_Connection = PM.Transport((host, port))
ssh_Connection.connect(username = username, password = password)
# Creaat SFTP CLIENT SERVICES
sftp = PM.SFTPClient.from_transport(ssh_Connection)
log.write("Connection Established...n")
remoteList = sftp.listdir(remotePath)
fileList = os.listdir(SRCfiles)
try:
sftp.chdir(remotePath+'/tmp')
except IOError:
sftp.mkdir(remotePath+'/tmp')
sftp.chdir(remotePath+'/tmp')
for fileName in fileList:
if 'comphaulier.asc' not in remoteList:
if 'Last' in fileName:
continue
else:
sftp.put(SRCfiles+'/'+fileName, remotePath+'/tmp/'+fileName)
log.write(fileName+" Transferredn")
else:
log.write("Files Still Existn")
log.close()
quit()
checkList = sftp.listdir(remotePath)
if len(checkList) == 7:
sftp.put(SRCfiles+'/LastFile.lst', remotePath+'/LastFile.lst')
log.write("LastFile.lst Transferredn")
else:
log.write("Not all files transferred!!!n")
quit()
sftp.close()
ssh_Connection.close()
os.system("rm LockSFTP")
Answers:
Use the sftp.rename
:
sftp.rename(remotePath+'/tmp/'+fileName, remotePath+fileName)
Note that some SFTP servers fail the request, if the source and target directories are on different file systems.
If you need to move set of files from one folder to another, see:
Archive all files from one SFTP folder to another in Python
I would suggest having also some safeguards. Sometimes the library will raise an IOError in certain conditions (the destination file exists already or the file to move does not exist). I will assume you have an sftp client sftp_client
def move_file(self, source, destination):
destination_file_exists = __file_exists(destination)
source_file_exists = __file_exists(source)
if destination_file_exists:
# handle the condition accordingly
print(f"destination file {destination} already exists")
else:
if source_file_exists:
sftp_client.rename(source, destination)
else:
# handle the condition accordingly
print(f"source file {source} does not exist")
def __file_exists(file_path):
try:
sftp_client.stat(file_path)
return True
except FileNotFoundError as e:
return False
except Exception as e:
print(e)
As you are already importing the os library use:
os.path.join(path, filename)
To obtain correct absolute paths and avoid dealing with duplicated or lacking / by the use of wild concatenations like above:
i.e.
f_w_current_path = os.path.join(current_path, f.filename)
f_w_temporary_path = os.path.join(temporary_path, f.filename)
sftp.rename(f_w_current_path, f_w_temporary_path)
the use of rename to move the file remotely with paramiko library it’s working for me.
I have a script that creates and tmp directory on an SFTP server and then puts files in said /tmp
once the transfer is complete however I need to move the files from /tmp
back one directory to root /
. Use Paramiko how would I move the files from one remote directory to another?
Step guide:
Local files —–> Remote Temporary Dir —-> Remote root Dir
Code below if needed:
#!/usr/bin/python
# --------------------------------------------------------------------
#import libraries
# --------------------------------------------------------------------
import paramiko as PM
import os
import datetime
# --------------------------------------------------------------------
# Global Variables
# --------------------------------------------------------------------
host = 'host IP address'
port = 22
username = 'Username'
password = '*********'
# Variable Paths
localPath = '/shares/MILKLINK/fromML'
remotePath = '/'
logPath = '/shares/MILKLINK/logs/PPcfg02.log'
SRCfiles = '/shares/MILKLINK/Milklink.cpy'
# --------------------------------------------------------------------
# Create LOG FILE
# --------------------------------------------------------------------
log = open(logPath, 'a')
log.write(datetime.datetime.now().isoformat()+'n')
# Creating lockfile
if(os.path.isfile('LockSFTP')):
log.write("LOCK FILE STILL EXISTS!")
quit()
else:
os.system(">LockSFTP")
# --------------------------------------------------------------------
# Remove all files from /formML/
# --------------------------------------------------------------------
fileList = os.listdir(localPath)
for fileName in fileList:
try:
os.remove(localPath+"/"+fileName)
except OSError:
log.write("%s could not be deletedn" % fileName)
# --------------------------------------------------------------------
# Create SFTP CONNECTION
# --------------------------------------------------------------------
log.write("Starting Connection...n")
# SSH connection
ssh_Connection = PM.Transport((host, port))
ssh_Connection.connect(username = username, password = password)
# Creaat SFTP CLIENT SERVICES
sftp = PM.SFTPClient.from_transport(ssh_Connection)
log.write("Connection Established...n")
remoteList = sftp.listdir(remotePath)
fileList = os.listdir(SRCfiles)
try:
sftp.chdir(remotePath+'/tmp')
except IOError:
sftp.mkdir(remotePath+'/tmp')
sftp.chdir(remotePath+'/tmp')
for fileName in fileList:
if 'comphaulier.asc' not in remoteList:
if 'Last' in fileName:
continue
else:
sftp.put(SRCfiles+'/'+fileName, remotePath+'/tmp/'+fileName)
log.write(fileName+" Transferredn")
else:
log.write("Files Still Existn")
log.close()
quit()
checkList = sftp.listdir(remotePath)
if len(checkList) == 7:
sftp.put(SRCfiles+'/LastFile.lst', remotePath+'/LastFile.lst')
log.write("LastFile.lst Transferredn")
else:
log.write("Not all files transferred!!!n")
quit()
sftp.close()
ssh_Connection.close()
os.system("rm LockSFTP")
Use the sftp.rename
:
sftp.rename(remotePath+'/tmp/'+fileName, remotePath+fileName)
Note that some SFTP servers fail the request, if the source and target directories are on different file systems.
If you need to move set of files from one folder to another, see:
Archive all files from one SFTP folder to another in Python
I would suggest having also some safeguards. Sometimes the library will raise an IOError in certain conditions (the destination file exists already or the file to move does not exist). I will assume you have an sftp client sftp_client
def move_file(self, source, destination):
destination_file_exists = __file_exists(destination)
source_file_exists = __file_exists(source)
if destination_file_exists:
# handle the condition accordingly
print(f"destination file {destination} already exists")
else:
if source_file_exists:
sftp_client.rename(source, destination)
else:
# handle the condition accordingly
print(f"source file {source} does not exist")
def __file_exists(file_path):
try:
sftp_client.stat(file_path)
return True
except FileNotFoundError as e:
return False
except Exception as e:
print(e)
As you are already importing the os library use:
os.path.join(path, filename)
To obtain correct absolute paths and avoid dealing with duplicated or lacking / by the use of wild concatenations like above:
i.e.
f_w_current_path = os.path.join(current_path, f.filename)
f_w_temporary_path = os.path.join(temporary_path, f.filename)
sftp.rename(f_w_current_path, f_w_temporary_path)
the use of rename to move the file remotely with paramiko library it’s working for me.