【问题标题】:Problems using multipart_encode (poster library)使用 multipart_encode 的问题(海报库)
【发布时间】:2012-05-19 18:13:57
【问题描述】:

我正在尝试使用multipart_encode 上传文件以实现MIME 进程。但是,我遇到了以下错误AttributeError: multipart_yielder instance has no attribute '__len__'。以下是我的方法,如果有人能给我一些建议,我真的很感激。

url = "https://pi-user-files.s3-external-1.amazonaws.com/"           
post_data = {}
#data is a dict
post_data['AWSAccessKeyId']=(data['ticket']['AWSAccessKeyId'])
post_data['success_action_redirect']=(data['ticket']['success_action_redirect'])
post_data['acl']=(data['ticket']['acl'])
post_data['key']=(data['ticket']['key'])
post_data['signature']=(data['ticket']['signature'])
post_data['policy']=(data['ticket']['policy'])
post_data['Content-Type']=(data['ticket']['Content-Type'])

#I would like to upload a text file "new 2"
post_data['file']=open("new  2.txt", "rb")

datagen, headers = multipart_encode(post_data)
request2 = urllib2.Request(url, datagen, headers)
result = urllib2.urlopen(request2)

【问题讨论】:

    标签: python mime encode multipartform-data poster


    【解决方案1】:

    如果你想发送文件,你应该用MultipartParam对象包装其他参数,创建发送文件请求的示例代码:

    from poster.encode import multipart_encode, MultipartParam
    import urllib2
    
    def postFileRequest(url, paramName, fileObj, additionalHeaders={}, additionalParams={}):
        items = []
        #wrap post parameters
        for name, value in additionalParams.items():
            items.append(MultipartParam(name, value))
        #add file
        items.append(MultipartParam.from_file(paramName, fileObj))
        datagen, headers = multipart_encode(items)
        #add headers
        for item, value in additionalHeaders.iteritems():
            headers[item] = value
        return urllib2.Request(url, datagen, headers)
    

    另外我认为你应该在开始时执行一次register_openers()。一些细节你可以在docs找到

    【讨论】:

      【解决方案2】:

      问题在于,在 httplib.py 中,生成器没有被检测到,而是被视为包含要发送的完整数据的字符串(因此它试图找到它的长度):

      if hasattr(data,'read') and not isinstance(data, array): # generator 
          if self.debuglevel > 0: print "sendIng a read()able"
          ....
      

      一种解决方案是让生成器像 read()able 一样工作:

      class GeneratorToReadable():
          def __init__(self, datagen):
              self.generator = datagen
              self._end = False
              self.data = ''
      
          def read(self, n_bytes):
              while not self._end and len(self.data) < n_bytes:
                  try:
                      next_chunk = self.generator.next()
                      if next_chunk:
                          self.data += next_chunk
                      else:
                          self._end = True
                  except StopIteration:
                      self._end = True
              result = self.data[0:n_bytes]
              self.data = self.data[n_bytes:]
              return result
      

      并像这样使用:

      datagen, headers = multipart_encode(post_data)
      readable = GeneratorToReadable(datagen)
      req = urllib2.Request(url, readable, headers)
      result = urllib2.urlopen(req)
      

      【讨论】:

        猜你喜欢
        • 2011-03-17
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 2021-06-25
        • 1970-01-01
        • 1970-01-01
        • 2020-03-01
        • 1970-01-01
        相关资源
        最近更新 更多