3

I'm calling the Paramiko sftp_client.put(locapath,remotepath) method

This is throwing the [Errno 2] File not found error below.

01/07/2020 01:12:03 PM - ERROR - [Errno 2] File not found
Traceback (most recent call last):
  File "file_transfer\TransferFiles.py", line 123, in main
  File "paramiko\sftp_client.py", line 727, in put
  File "paramiko\sftp_client.py", line 689, in putfo
  File "paramiko\sftp_client.py", line 460, in stat
  File "paramiko\sftp_client.py", line 780, in _request
  File "paramiko\sftp_client.py", line 832, in _read_response
  File "paramiko\sftp_client.py", line 861, in _convert_status

Having tried many of the other recommend fixes I found that the error is due to the server having an automatic trigger to move the file immediately to another location upon the file being uploaded.

I've not seen another post relating to this issue and wanted to know if anyone else has fixed this as the SFTP server is owned by a third party and not wanting to change trigger attributes.

The file actually uploads correctly, so I could catch the Exception and ignore the error. But I'd prefer to handle it, if possible.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Tintin
  • 33
  • 4

2 Answers2

1

Paramiko by default verifies a size of the uploaded file after the upload.

If the file is moved away immediately after upload, the check fails.

To avoid the check, set confirm parameter of SFTPClient.put to False.

sftp_client.put(localpath, remotepath, confirm=False)

I believe the check is redundant anyway, see
How to perform checksums during a SFTP file transfer for data integrity?


For a similar question about pysftp (what is a wrapper around Paramiko), see:
Python pysftp.put raises "No such file" exception although file is uploaded

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
0

Also had this issue of the file automatically getting moved before paramiko could do an os.stat on the uploaded file and compare the local and uploaded file sizes.

@Martin_Prikryl solution works works fine for removing the error by passing in confirm=False when using sftp.put or sftp.putfo

If you want this check to still run like you mention in the post to see if the file has been uploaded fully you can run something along these lines. For this to work you will need to know the moved file location and have the ability to read the file.

import os

sftp.putfo(source_file_object, destination_file, confirm=False)
upload_size = sftp.stat(moved_path).st_size
local_size = os.stat(source_file_object).st_size
if upload_size != local_size:
    raise IOError(
        "size mismatch in put!  {} != {}".format(upload_size, local_size)
    )

Both checks use os.stat

mRyan
  • 332
  • 4
  • 18