无法从 App Engine 中的 FTP 服务器下载 csv 文件

unable to dowload csv file from FTP server in app engine

我正在尝试从 AppEngine 中的 ftp 服务器读取 CSV 文件,并且我能够连接到 ftp 服务器。但是当我试图检索文件时它返回错误。 这是我从服务器读取 CSV 文件的代码:

import ftplib
import cStringIO
import csv

session = ftplib.FTP('myftpserver.com')
session.login('username','pwd')
session.set_pasv(False)

output = cStringIO.StringIO()

session.retrbinary('RETR myfile.csv', output.write)
csvfile = csv.reader(output.getvalue().splitlines(), delimiter=',')

for i, row in enumerate(csvfile):
    print row

这是我得到的错误的回溯:

  Traceback (most recent call last):
  File "/home/vikas/apps/myproj/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/home/vikas/apps/myproj/admin/admin_actions.py", line 3528, in get_ftp_file
    session.retrbinary('RETR myfile.csv', output.write)
  File "/usr/lib/python2.7/ftplib.py", line 414, in retrbinary
    conn = self.transfercmd(cmd, rest)
  File "/usr/lib/python2.7/ftplib.py", line 376, in transfercmd
    return self.ntransfercmd(cmd, rest)[0]
  File "/usr/lib/python2.7/ftplib.py", line 354, in ntransfercmd
    sock = self.makeport()
  File "/usr/lib/python2.7/ftplib.py", line 283, in makeport
    for res in socket.getaddrinfo(None, 0, self.af, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
  File "/home/vikas/gcloud/google-cloud-sdk/platform/google_appengine/google/appengine/api/remote_socket/_remote_socket.py", line 318, in getaddrinfo
    raise gaierror(EAI_NONAME, 'nodename nor servname provided, or not known')
gaierror: [Errno 8] nodename nor servname provided, or not known

我不知道我做错了什么,none dir() nlst() 等命令正在运行,我一添加它们就出现了上述错误。

唉,App Engine 当前提供的套接字模拟还不够好,无法涵盖所有​​用例。

这是一个访问著名的 public 匿名 FTP 服务器并从中获取一个小文本文件的示例,这样每个人都可以重现和实验...:在文件 getit.py,我们有:

import ftplib
import cStringIO

def getit():
    session = ftplib.FTP('ftp.mozilla.org')
    session.login('anonymous','')
    # session.set_pasv(False)
    session.cwd('/pub/mozilla.org')

    output = cStringIO.StringIO()
    session.retrbinary('RETR README', output.write)

    return output.getvalue()

if __name__ == '__main__':
    print(getit())

这作为独立运行良好,python getit.py,无论您是将 set_pasv 保留为此处的评论,还是删除评论。

将其嵌入到 GAE 应用程序中,例如:

import getit
class GetitPage(webapp2.RequestHandler):
  def get(self):  # pylint:disable-msg=invalid-name
     try: result = getit.getit()
     except Exception as e:
         result = 'Error {}: {}'.format(type(e), e)
     self.response.headers['Content-Type'] = 'text/plain'
     self.response.out.write(result)

这对 set_pasv 留下的评论很好用,但如果你取消评论,你会得到与你收到的基本相同的异常。

因此,对强制您进入主动模式(不支持被动模式)的服务器执行 FTP 不会以这种方式工作。但是, 一个相当损坏的服务器 -- 你能修复它以便它支持流行的默认被动模式吗?然后您的 GAE 应用程序可以愉快地使用它...!