Отправить файл корзины на FTP-сервер, используя pysftp - PullRequest
0 голосов
/ 15 марта 2020

Я пытаюсь отправить файл из корзины на FTP-сервер, используя pysftp.

Для этого я использую облачные функции Google с python 3.7

Я пробовал разными способами, но всегда с ошибкой.

1.- Загрузка файла в виде строки : в этом примере, чтобы избежать ошибки с содержимым файла, я создам файл, который содержит «тестовую строку», вместо того, чтобы использовать то, что находится внутри файла корзины

def sftp_handler():
    myHostname = "hotsname.com"
    myUsername = "username"
    myPassword = "pass"
    try:
        keydata = b"""AAAAB..."""
        key = paramiko.RSAKey(data=decodebytes(keydata))
        cnopts = pysftp.CnOpts()
        cnopts.hostkeys.add('hotname.com', 'ssh-rsa', key)
        with pysftp.Connection(host=myHostname, username=myUsername, password=myPassword,port=22,cnopts=cnopts) as sftp:
            print ("Connection succesfully stablished ... ")
            remoteFilePath = '/dir1/dir2/dir3/'
            sftp.putfo(StringIO('test string'), os.path.join(remoteFilePath, "OC.csv"))            
        # connection closed automatically at the end of the with-block
    except:
        print("Unexpected error in sftp_handler:")
        traceback.print_exc()

Вывод ошибки (журнал стека)

Traceback (most recent call last): E    undefined
File "/user_code/main.py", line 36, in sftp_handler E  
sftp.putfo(StringIO('xml string'), os.path.join(remoteFilePath, "OC.csv")) E  
File "/env/local/lib/python3.7/site-packages/pysftp/__init__.py", line 474, in putfo E  
callback=callback, confirm=confirm) E  
File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 714, in putfo E  
with self.file(remotepath, "wb") as fr: E  
File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 372, in open E  
t, msg = self._request(CMD_OPEN, filename, imode, attrblock) E  
File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 813, in _request E  
return self._read_response(num) E  
File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 865, in _read_response E  
self._convert_status(msg) E 
File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 898, in _convert_status E  
raise IOError(text) 
 OSError E  

2.- Использование временного файла , в который я запишу содержимое файла из корзины

<adding this to the previous code>
with tempfile.NamedTemporaryFile(suffix='.csv', prefix=os.path.basename(__file__)) as tf:
      tf.write(b'Hello world!')
      remoteFilePath = '/dir1/dir2/dir3/'
      sftp.put(os.path.dirname(tf.name), os.path.join(remoteFilePath, "OC.csv"))

Журнал ошибок:

 Traceback (most recent call last): E  
   File "/user_code/main.py", line 40, in sftp_handler E  
     sftp.put(os.path.dirname(tf.name), os.path.join(remoteFilePath, "OC.csv")) E  
   File "/env/local/lib/python3.7/site-packages/pysftp/__init__.py", line 364, in put E  
     confirm=confirm) E  
   File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 758, in put E  
     with open(localpath, "rb") as fl: E  
 IsADirectoryError: [Errno 21] Is a directory: '/tmp' E  

3.- Как предложил Мартин в своем ответе:

    with pysftp.Connection(host=myHostname, username=myUsername, password=myPassword,port=22,cnopts=cnopts) as sftp:
        print ("Connection succesfully stablished ... ")
        remoteFilePath = '/dir1/dir2/dir3/'
        sftp.putfo(StringIO('test string'), remoteFilePath + "OC.csv")

Я получаю следующую ошибку:

 Traceback (most recent call last): E  
   File "/user_code/main.py", line 36, in sftp_handler E  
     sftp.putfo(StringIO('test string'), remoteFilePath + "OC.csv") E  
   File "/env/local/lib/python3.7/site-packages/pysftp/__init__.py", line 474, in putfo E  
     callback=callback, confirm=confirm) E  
   File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 714, in putfo E  
     with self.file(remotepath, "wb") as fr: E  
   File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 372, in open E  
     t, msg = self._request(CMD_OPEN, filename, imode, attrblock) E  
   File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 813, in _request E  
     return self._read_response(num) E  
   File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 865, in _read_response E  
     self._convert_status(msg) E  
   File "/env/local/lib/python3.7/site-packages/paramiko/sftp_client.py", line 898, in _convert_status E  
     raise IOError(text) E  
 OSError E 

4.- Загрузка файла из корзины, создание файла при выполнении облачных функций и отправка этого файла в sftp (пока не реализовано, так как я не уверен, будет ли он работать при создании файла в облачной функции)


  1. Как я мог это сделать?
  2. Почему происходит сбой?

Примечание: Я также пытался использовать FileZilla, и у меня также есть ошибка, поэтому это должно быть что-то связанное с сервером FTP:

09:00:46    Status: Connecting to sftp-staging.messagesnetwork.com...
09:01:06    Status: Connected to sftp-staging.messagesnetwork.com
09:01:06    Status: Retrieving directory listing...
09:01:06    Status: Listing directory /
09:01:07    Status: Directory listing of "/" successful
09:01:11    Status: Retrieving directory listing of "/folder1"...
09:01:37    Command:    cd "folder1"
09:01:37    Response:   New directory is: "/folder1"
09:01:37    Command:    ls
09:01:37    Error:  Connection timed out after 20 seconds of inactivity
09:01:38    Error:  Failed to retrieve directory listing
09:01:38    Status: Disconnected from server
09:01:38    Status: Connecting to sftp-staging.messagesnetwork.com...
09:02:04    Status: Connected to sftp-staging.messagesnetwork.com
09:02:09    Status: Retrieving directory listing of "/folder1"...
09:02:10    Status: Listing directory /folder1
09:02:10    Status: Directory listing of "/folder1" successful
09:02:12    Status: Retrieving directory listing of "/folder1/folder2"...
09:02:21    Status: Listing directory /folder1/folder2
09:02:23    Status: Directory listing of "/folder1/folder2" successful
09:02:24    Status: Retrieving directory listing of "/folder1/folder2/folder3"...
09:02:25    Status: Listing directory /folder1/folder2/folder3
09:02:26    Status: Directory listing of "/folder1/folder2/folder3" successful
09:02:30    Status: Connecting to sftp-staging.messagesnetwork.com...
09:02:41    Status: Connected to sftp-staging.messagesnetwork.com
09:02:45    Status: Starting upload of <...>\Desktop\folder2cf.txt
09:02:59    Command:    cd "/folder1/folder2/folder3"
09:02:59    Response:   New directory is: "/folder1/folder2/folder3"
09:02:59    Command:    put "<...>\Desktop\folder2cf.txt" "folder2cf.txt"
09:02:59    Error:  /folder1/folder2/folder3/folder2cf.txt: open for write: failure
09:02:59    Error:  File transfer failed
09:02:59    Status: Starting upload of <...>\Desktop\folder2cf.txt
09:02:59    Status: Retrieving directory listing of "/folder1/folder2/folder3"...
09:02:59    Status: Listing directory /folder1/folder2/folder3
09:03:11    Command:    put "<...>\Desktop\folder2cf.txt" "folder2cf.txt"
09:03:11    Error:  /folder1/folder2/folder3/folder2cf.txt: open for write: failure
09:03:11    Error:  File transfer failed
09:03:11    Status: Starting upload of <...>\Desktop\folder2cf.txt
09:03:11    Status: Retrieving directory listing of "/folder1/folder2/folder3"...
09:03:11    Status: Listing directory /folder1/folder2/folder3
09:03:34    Command:    put "<...>\Desktop\folder2cf.txt" "folder2cf.txt"
09:03:34    Error:  /folder1/folder2/folder3/folder2cf.txt: open for write: failure
09:03:34    Error:  File transfer failed
09:03:34    Status: Retrieving directory listing of "/folder1/folder2/folder3"...
09:03:39    Status: Listing directory /folder1/folder2/folder3
09:03:44    Status: Directory listing of "/folder1/folder2/folder3" successful

1 Ответ

1 голос
/ 16 марта 2020
sftp.putfo(StringIO('test string'), os.path.join(remoteFilePath, "OC.csv"))

Я не могу сказать атм, если это реальная проблема, но вы не должны использовать path.join для путей SFTP. SFTP всегда использует forward sla sh. path.join использует разделитель локальной операционной системы. Может отличаться (особенно на Windows).

Код должен быть:

remoteFilePath = '/dir1/dir2/dir3/'
sftp.putfo(StringIO('test string'), remoteFilePath + "OC.csv")

sftp.put(os.path.dirname(tf.name), os.path.join(remoteFilePath, "OC.csv"))

Использование path.dirname здесь есть смысл. Вы хотите загрузить файл, поэтому вам нужно указать путь к файлу для загрузки, а не путь к папке, в которой он находится.

И с path.join такая же проблема, как и раньше.

...