1

I am trying to upload files from C:/Test/ folder. Code:

import pysftp
import os
host = host
port = 22
username = username
password= pass
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
try:
  conn = pysftp.Connection(host=host,port=port,username=username, password=password, cnopts=cnopts)
  print("connection established successfully")
except:
  print('failed to establish connection to targeted server')
files=os.listdir('C:/Test/')
with conn.cd('/'):
    for file in files:
            try:
                conn.put(file)
                print('uploaded file successfully: ',file)
            except:
                print('failed to upload file: ',file)

And I am getting error:

"failed to upload file" or "NoneType object has no attribute time"

But this code works fine for one file. What am I doing wrong?

This is Error:
failed to upload file:  Test.pdf
Exception ignored in: <function Connection.__del__ at 0x000001C180B71B40>
Traceback (most recent call last):
  File "C:\Python\lib\site-packages\pysftp\__init__.py", line 1013, in __del__
  File "C:\Python\lib\site-packages\pysftp\__init__.py", line 785, in close
  File "C:\Python\lib\site-packages\paramiko\sftp_client.py", line 195, in close
  File "C:\Python\lib\site-packages\paramiko\channel.py", line 671, in close
  File "C:\Python\lib\site-packages\paramiko\transport.py", line 1901, in _send_user_message
AttributeError: 'NoneType' object has no attribute 'time'
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Kirill
  • 11
  • 3

1 Answers1

0

The os.listdir returns file names only. You have to pass full path to the pysftp Connection.put.

You would easily learn that had you not swallowed the actual exception:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    conn.put(file)
  File "C:\...\Python\Python39\lib\site-packages\pysftp\__init__.py", line 363, in put
    sftpattrs = self._sftp.put(localpath, remotepath, callback=callback,
  File "C:\...\Python\Python39\lib\site-packages\paramiko\sftp_client.py", line 757, in put
    file_size = os.stat(localpath).st_size
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'test.log'  

The code should be like:

localpath = "C:/Test/"
files = os.listdir(localpath)
with conn.cd("/"):
    for file in files:
        if file[-4:]=='.log':
            try:
                conn.put(os.path.join(localpath, file))
                print('uploaded file successfully: ',file)
            except:
                print('failed to upload file: ',file)

Or simply change the working directory to the source path:

os.chdir("C:/Test/")
files = os.listdir(".")
with conn.cd("/"):
    for file in files:
        if file[-4:]=='.log':
            try:
                conn.put(file)
                print('uploaded file successfully: ',file)
            except:
                print('failed to upload file: ',file)

Obligatory warnings:

  • Do not set cnopts.hostkeys = None, unless you do not care about security. For the correct solution see Verify host key with pysftp.

  • Though these days, you should not use pysftp, as it is dead. Use Paramiko directly instead. See pysftp vs. Paramiko.

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