I am working on an application where I have to upload a file to the remote server.
I then wait for the file to process and sftp the processed file back to the original server.
I have managed to copy the file to the remote server using paramiko module.
How do I achieve the following?
Create a criteria for checking whether the result file is generated on a loop basis, and
Only proceed with the sftp once the file has been created in the remote folder.
Here is my code what i have tried so far
s = open("sea" + str(UID), 'w')
s.write(outtext)
s.close()
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("XXXX", username="XXXX", password="XXXXX")
sftp = ssh.open_sftp()
currentfile=pwd + "/sea" + str(UID)
print currentfile
destinationfile="/srv/sftp/smc-sftp-DEFAULT/inbox/sea" + str(UID)
sftp.put(currentfile,destinationfile)
outputfile="/srv/sftp/smc-sftp-DEFAULT/outbox/"
finalfile="/sea" + str(UID) + ".res"
while True:
try:
print(sftp.stat(outputfile+finalfile))
print('file exists')
sftp.get(outputfile+finalfile,pwd + "/sea" + str(UID) + ".res")
break
except IOError:
print('copying file')
continue
sftp.close()
ssh.close()
the issue is now solved.
it was a mistake in defining the outputfile with an extra "/"
changed them to below value.
outputfile="/srv/sftp/smc-sftp-DEFAULT/outbox"
Related
I'm trying to create a python application that allows you to transfer files from the client to a server. The operation consists in sending a string to the server to indicate that we are sending a file and then the client sends the file name, its length and finally the contents of the file to the server. finally, the server confirms that the file has been saved and sends the confirmation message to the client
client.py
c.send(f"FILES:{files};{folder[index:]}".encode(FORMAT))
msg = c.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
for i in range(len(files)):
c.send(files[i].encode(FORMAT))
print(f"[SERVER]: {c.recv(SIZE).decode(FORMAT)}") # send fileName
length = os.path.getsize(folder + "\\" + files[i])
c.send(str(length).encode(FORMAT))
print(f"[SERVER]: {c.recv(SIZE).decode(FORMAT)}") # send size
file = open(folder + "\\" + files[i], 'rb')
print(f"File read: {file.read()}")
try:
c.send(file.read()) #send bytes of file
except Exception as e:
print(f"[ERROR]: {e}")
print(f"[SERVER]: {c.recv(SIZE).decode(FORMAT)}") # complete writing on server
server.py
elif cmd == "FILES":
try:
data, path = data.split(';')
conn.send("Received files".encode(FORMAT))
while True:
nameFile = conn.recv(SIZE).decode(FORMAT)
conn.send(f"Received FileName {nameFile}".encode(FORMAT)) # received fileName
file = open(basePath + "\\" + path + "\\" + nameFile, 'wb')
print(f"[SERVER]: Opened: {file}")
length = conn.recv(SIZE).decode(FORMAT)
print(f"[CLIENT]: Length of files: {length}")
conn.send("Received size".encode(FORMAT)) # received size
bytesSend = conn.recv(length)
print(f"[CLIENT] Received bytes: {conn.recv(length)}")
file.write(bytesSend)
file.close
conn.send(f"File {nameFile} receive and saved".encode(FORMAT)) #complete writing
except:
pass
But when I try to send everything works up to c.send(file.read()). practically the client sends (but in reality it does not) the contents of the file to the server and passes to the last c.recv where it waits for the server confirmation but the server does not receive any contents of the file. Consequently, the server waits for the contents of the file to arrive but the client times out as it waits for confirmation from the server.
Aim: I am trying to use SFTP through Paramiko in Python to upload files on server pc.
What I've done: To test that functionality, I am using my localhost (127.0.0.1) IP. To achieve that I created the following code with the help of Stack Overflow suggestions.
Problem: The moment I run this code and enter the file name, I get the "IOError : Failure", despite handling that error. Here's a snapshot of the error:
import paramiko as pk
import os
userName = "sk"
ip = "127.0.0.1"
pwd = "1234"
client=""
try:
client = pk.SSHClient()
client.set_missing_host_key_policy(pk.AutoAddPolicy())
client.connect(hostname=ip, port=22, username=userName, password=pwd)
print '\nConnection Successful!'
# This exception takes care of Authentication error& exceptions
except pk.AuthenticationException:
print 'ERROR : Authentication failed because of irrelevant details!'
# This exception will take care of the rest of the error& exceptions
except:
print 'ERROR : Could not connect to %s.'%ip
local_path = '/home/sk'
remote_path = '/home/%s/Desktop'%userName
#File Upload
file_name = raw_input('Enter the name of the file to upload :')
local_path = os.path.join(local_path, file_name)
ftp_client = client.open_sftp()
try:
ftp_client.chdir(remote_path) #Test if remote path exists
except IOError:
ftp_client.mkdir(remote_path) #Create remote path
ftp_client.chdir(remote_path)
ftp_client.put(local_path, '.') #At this point, you are in remote_path in either case
ftp_client.close()
client.close()
Can you point out where's the problem and the method to resolve it?
Thanks in advance!
The second argument of SFTPClient.put (remotepath) is path to a file, not a folder.
So use file_name instead of '.':
ftp_client.put(local_path, file_name)
... assuming you are already in remote_path, as you call .chdir earlier.
To avoid a need for .chdir, you can use an absolute path:
ftp_client.put(local_path, remote_path + '/' + file_name)
Got this error while running my script:
ftplib.error_perm: 550 Requested action not taken.
ftp = FTP()
HOST = 'some host here'
PORT = 'some port here'
ftp.connect(host=HOST, port=PORT)
ftp.login(user="some_user", passwd="pass")
out = 'ftp_files/'
filenames = ftp.nlst()
for file in filenames:
file = file[::-1]
file = file.split(' ')[0]
file = file[::-1] # file name is ready
with open(out + file, 'wb') as f:
ftp.retrbinary('RETR ' + file, f.write)
ftp.close()
I've changed pass, username, host and port in this example. They are correct in real.
If anybody knows what the problem can be?
It falls only on one file that is empty. I still don't know if this was the problem, but i will look for anoher solution in my project. Current ftp isn's stable in work.
Sometimes, FTP server closes connection before file is completely downloaded..
Here is my code:
ftp = ftplib.FTP(site)
ftp.login(user, pw)
ftp.cwd(dir)
remotefiles = ftp.nlst()
for file in remotefiles:
if fnmatch.fnmatch(file, match_text):
if os.path.exists(file):
if True: print file, 'already fetched'
else:
if True: print 'Downloading', file
local = open(file, 'wb')
try:
ftp.retrbinary('RETR ' + file, local.write)
finally:
local.close()
if True: print 'Download done.'
You can specify a timeout parameter in the FTP constructor and set it to 0 or something very large value like sys.maxint.
class ftplib.FTP([host[, user[, passwd[, acct[, timeout]]]]])
Additionally, you can turn on debugging to see what's going on behind the scenes.
ftp = ftplib.FTP(site, user, pw, timeout=0)
ftp.set_debuglevel(2)
Hope this helps.
Very new to Python, and coding in general.
I have been working on processing csv files and uploading them to a SFTP server. I wish to check whether the file exists on the server. If it does exist, I want to rename it and archive it to another folder then replace with updated file. If it doesn't exist...I simply want to upload the file.
path2 = '/import/Test/stock_update.csv'
ssh = paramiko.SSHClient()
paramiko.util.log_to_file(log_file)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dt = str(datetime.datetime.now())
newname = dt+'stock_update.csv'
archive = 'import/Test/Done/'+newname
ssh.connect('xxxx-mediaserverxxxxxxxxx', port=22, username='xxxxxxxxx', password='xxxxxxxxxx')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('ls /tmp')
print "output", ssh_stdout.read() #Reading output of the executed co'mmand
error = ssh_stderr.read()
print "err", error, len(error)
sftp = ssh.open_sftp()
try:
sftp.stat(path2)
except IOError as e:
print e.errno
print errno.ENOENT
if e.errno == errno.ENOENT:
print 'this is if'
sftp.put('C:/Test/fun/stock_update.csv','/import/Test/stock_update.csv',)
else:
print 'this is else'
sftp.rename('/import/Test/stock_update.csv',archive)
sftp.put('C:/Test/fun/stock_update.csv','/import/Test/stock_update.csv',)
finally:
sftp.close()
ssh.close()
I think I am improperly using the else? A file is created on the SFTP server if none exists but nothing is done if the file exists. Individually the lines of code do work.