【问题标题】:Send a bucket file to FTP server using pysftp使用 pysftp 将存储桶文件发送到 FTP 服务器
【发布时间】:2020-03-15 19:14:54
【问题描述】:

我正在尝试使用 pysftp 将文件从存储桶发送到 FTP 服务器。

为此,我在 python 3.7 中使用 Google 云函数

我尝试了很多不同的方法,但总是出错。

1.- Downloading the file as string:在这个例子中,为了避免文件内容出错,我将创建一个包含“测试字符串”的文件,而不是使用存储桶文件中的内容

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()

错误输出(stackdriver log)

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.- Using a temp file 我将从桶中写入文件的内容

<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

【问题讨论】:

    标签: python google-cloud-functions sftp pysftp


    【解决方案1】:
    sftp.putfo(StringIO('test string'), os.path.join(remoteFilePath, "OC.csv"))
    

    我不能说 atm,如果这是真正的问题,但您不应该将 path.join 用于 SFTP 路径。 SFTP 始终使用正斜杠。 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 也存在与之前相同的问题。

    【讨论】:

    • 谢谢马丁。以前我使用:sftp.put(StringIO('test string'), os.path.join("/dir1/dir2/dir3/OC.csv")) 进行了测试,但出现了错误,现在我尝试了您的:sftp.putfo(StringIO('test string'), remoteFilePath + "OC.csv"),所以我认为您的选择(也是我的)很好,但我遇到了错误,我不知道为什么。我将上传带有错误日志的主帖
    • 您可以使用任何(GUI)SFTP 客户端将文件上传到/dir1/dir2/dir3/OC.csv 吗?向我们展示一个日志文件。
    • 这应该是来自 FTP 服务器的错误,因为我尝试过使用 Filezilla 并且我也遇到了同样的错误。在它工作的前几天,所以我会问一下 FTP
    猜你喜欢
    • 1970-01-01
    • 2023-01-26
    • 2021-07-06
    • 2020-06-20
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    相关资源
    最近更新 更多