1

I'm trying to copy a file from my local to an SFTP but somehow I keep getting stuck in some error that I'm not able to fix. I attach below the code I wrote since now taking as examples what I found here on Stack Overflow.

local_dir = '/local/dir'
local_file = 'test_file_sftp.csv'
localpath = os.path.join(local_dir, local_file)
remotepath = '/remote/path/'
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None

with pysftp.Connection(host='xx.xx.xx.xx',
                       username='some_name',
                       private_key='key',
                       cnopts=cnopts) as sftp:
    
    sftp.put_r(localpath, remotepath)
    print('Upload finished')

And this is the main error I wasn't able to solve since now:

NotADirectoryError                        Traceback (most recent call last)
Input In [40], in <cell line: 12>()
     11 #set connection and put file into sftp
     12 with pysftp.Connection(host=host, username=username, private_key=private_key, cnopts=cnopts) as sftp:
---> 14     sftp.put_r(localpath, remotepath)
     15     print('- Upload finished!')

File /opt/anaconda3/envs/sky_roi/lib/python3.10/site-packages/pysftp/__init__.py:427, in Connection.put_r(self, localpath, remotepath, confirm, preserve_mtime)
    425 wtcb = WTCallbacks()
    426 cur_local_dir = os.getcwd()
--> 427 os.chdir(localpath)
    428 walktree('.', wtcb.file_cb, wtcb.dir_cb, wtcb.unk_cb)
    429 # restore local directory

NotADirectoryError: [Errno 20] Not a directory: '/Users/xyz/aaa/ab/cd/ef/test_file_sftp.csv'

I'm new to pysftp and SFTP in general, so any kind of hint will be greatly appreciated.

If I eliminate the file from the directory string localpath, the code works but it simply uploads the whole folder (obviously!) instead of the single file I want. Any advise on this? Maybe I'm missing something very basic and I'm not noticing it

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
GLTCL
  • 13
  • 3

3 Answers3

0

As you can see here, to merge the path "/local/dir/" with the file "test_file_sftp" you dont need the "/" before the filename.

If you write "/test_file_sftp" looks like this file is in "/".

  • Many thanks for the answer. I actually updated the paths as follows: local_dir = '/local/dir' local_file = 'test_file_sftp' But the error still remains – GLTCL Dec 20 '22 at 12:04
  • ¿The file exists? – Juan Andrés Martinez Dec 20 '22 at 16:21
  • Yes, it always existed. The problem was that I was using connection.put_r (used to upload whole folders) instead of connection.put (used to upload single files) :) – GLTCL Dec 20 '22 at 16:24
0

Try to test if your file exists in that directory:

#list the files in the path of the local_dir you provided
print(os.listdir(local_dir))
#list files in the current directory you are in:
dir_path = os.getcwd()
print(os.listdir(dir_path))

and then update the path according to that

alphaBetaGamma
  • 653
  • 6
  • 19
0

The Connection.put_r is for uploading folders. You are uploading a file, so use Connection.put. Though it requires a path to a remote file in the remotepath argument. So you need to add the filename:

local_dir = '/local/dir'
filename = 'test_file_sftp.csv'
localpath = os.path.join(local_dir, filename)
remote_dir = '/remote/path/'
remotepath = remote_dir + filename

sftp.put_r(local, remotepath)

Side notes:

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thank you very much!! I was able to fix and run the code successfully! Much appreciated :) – GLTCL Dec 20 '22 at 13:04