28

I wrote a simple code to upload a file to a SFTP server in Python. I am using Python 2.7.

import pysftp

srv = pysftp.Connection(host="www.destination.com", username="root",
password="password",log="./temp/pysftp.log")

srv.cd('public') #chdir to public
srv.put('C:\Users\XXX\Dropbox\test.txt') #upload file to nodejs/

# Closes the connection
srv.close()

The file did not appear on the server. However, no error message appeared. What is wrong with the code?

I have enabled logging. I discovered that the file is uploaded to the root folder and not under public folder. Seems like srv.cd('public') did not work.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
guagay_wk
  • 26,337
  • 54
  • 186
  • 295

3 Answers3

43

I found the answer to my own question.

import pysftp

srv = pysftp.Connection(host="www.destination.com", username="root",
password="password",log="./temp/pysftp.log")

with srv.cd('public'): #chdir to public
    srv.put('C:\Users\XXX\Dropbox\test.txt') #upload file to nodejs/

# Closes the connection
srv.close()

Put the srv.put inside with srv.cd

guagay_wk
  • 26,337
  • 54
  • 186
  • 295
18

Do not use pysftp it's dead. Use Paramiko directly. See also pysftp vs. Paramiko.


The code with Paramiko will be pretty much the same, except for the initialization part.

import paramiko
 
with paramiko.SSHClient() as ssh:
    ssh.load_system_host_keys()
    ssh.connect(host, username=username, password=password)
 
    sftp = ssh.open_sftp()

    sftp.chdir('public')
    sftp.put('C:\Users\XXX\Dropbox\test.txt', 'test.txt')

To answer the literal OP's question: the key point here is that pysftp Connection.cd works as a context manager (so its effect is discarded without with statement), while Paramiko SFTPClient.chdir does not.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
9
import pysftp

with pysftp.Connection(host="www.destination.com", username="root",
password="password",log="./temp/pysftp.log") as sftp:

  sftp.cwd('/root/public')  # The full path
  sftp.put('C:\Users\XXX\Dropbox\test.txt')  # Upload the file

No sftp.close() is needed, because the connection is closed automatically at the end of the with-block

I did a minor change with cd to cwd

Syntax -

# sftp.put('/my/local/filename')  # upload file to public/ on remote
# sftp.get('remote_file')         # get a remote file
Ilja Leiko
  • 426
  • 2
  • 7
  • 22
Amit Ghosh
  • 1,500
  • 13
  • 18