title: Flask and Nova glance download: TypeError: object of type 'generator' has no len()
body: <p>I am having a head-heck with a piece of code.
  I am developing an Openstack Nova driver, which needs at some point to download a Glance image to a remote server. This remote server hosts a Flask web server which has a REST API to allow content to be downloaded (POST /api/images/pull).
  When I try the code, I get the following error: "TypeError: object of type 'generator' has no len()".</p>
  
  <p>Here is the code on the Nova side:</p>
  
  <pre><code>def pull_image(self, image_obj, context, image_href):
      # Put the Glance image to the Wparrip server
      (image_service, image_id) = glance.get_remote_image_service(context,image_href)
      read_iter = image_service.download(context, image_id)
      image_size = image_obj.get_image_size(context, image_href)
      headers = {
           'Content-Type': 'application/octet-stream',
           'Content-Length': image_size,
           'Transfer-encoding':'chunked',
           'Cache-Control': 'no-cache',
           'Connection': 'Keep-Alive',
           'X-Meta-Glance-Image-Id': image_href
      }
      def _get_next():
          for chunk in read_iter:
              if chunk:
                  yield chunk
  
      resp = self._make_request('POST','/api/images/pull',headers=headers, body=_get_next())
      if resp.code != 200:
          raise Exception(_("Cannot create_container %s") % format(resp.code))
      return True
  </code></pre>
  
  <p>And here is the code on the Flask server side:</p>
  
  <pre><code>@app.route('/wparrip/api/images/pull', methods = ['POST'])
  @crossdomain(origin='*')
  def image_download():
      """
      The other way around... we download an image coming from
      Glance (or another source __future__). 
      """
      local_filename="test.tgz"
      file = os.path.join(image_local,local_filename)
      f = open(file, 'wb')
      while True:
          data = request.data
          if data:
              f.write(data)
              f.flush()
          else:
              f.close()
              break
      resp = make_response(jsonify( {'file':file} ), 200)
      return resp
  </code></pre>
  
  <p>So, here is the _make_request function:</p>
  
  <pre><code>def _make_request(self, *args, **kwargs):
      headers = {}
      if 'headers' in kwargs and kwargs['headers']:
          headers = kwargs['headers']
      if 'Content-Type' not in headers:
          headers['Content-Type'] = 'application/json'
          kwargs['headers'] = headers
      rest = httplib.HTTPConnection(self._host_ip,self._host_port)
      if rest is None:
          raise Exception(_("Cannot create the Http remote Connection"))
  
      rest.request(*args, **kwargs)
      return rest_utils.Response(rest.getresponse())
  </code></pre>
  
  <p>Does anyone can help me figure out what is wrong in this piece of code?</p>
  
  <p>Here is the error log on nova side (Flask side is not interesting, except that we do pass in the piece of code I sent)</p>
  
  <pre><code>    2014-02-21 15:46:55.101   [00;32mDEBUG glanceclient.common.http [  [00;36m-  [00;32m]   [01;35m  [00;32mcurl -i -X HEAD -H 'X-Service-Catalog: [{"endpoints": [{"adminURL": "http://10.197.160.95:8776/v1/174a21dd0de043719d87c7c9e2f9d062", "region": "RegionOne", "internalURL": "http://10.197.160.95:8776/v1/174a21dd0de043719d87c7c9e2f9d062", "id": "11b750f23e9b4c36bb9d1948cdfb0ad6", "publicURL": "http://10.197.160.95:8776/v1/174a21dd0de043719d87c7c9e2f9d062"}], "endpoints_links": [], "type": "volume", "name": "cinder"}]' -H 'X-Identity-Status: Confirmed' -H 'X-Roles: admin' -H 'User-Agent: python-glanceclient' -H 'X-Tenant-Id: 174a21dd0de043719d87c7c9e2f9d062' -H 'X-User-Id: 451d46cd619243668658c92f8a1a29a4' -H 'X-Auth-Token: af6606b8713d09b2f85b308098e4c7d7' -H 'Content-Type: application/octet-stream' http://10.197.160.95:9292/v1/images/b408d525-3186-4200-a9a7-90eaf756b843  [00m   [00;33mfrom (pid=836) log_curl_request /opt/stack/python-glanceclient/glanceclient/common/http.py:142  [00m
  2014-02-21 15:46:55.121   [00;32mDEBUG glanceclient.common.http [  [00;36m-  [00;32m]   [01;35m  [00;32m
  HTTP/1.1 200 OK
  content-length: 0
  x-image-meta-id: b408d525-3186-4200-a9a7-90eaf756b843
  date: Fri, 21 Feb 2014 14:46:55 GMT
  x-image-meta-deleted: False
  x-image-meta-checksum: 3a106675dfc12795963726e7b9cf53b0
  x-image-meta-container_format: wparrip
  x-image-meta-protected: False
  x-image-meta-min_disk: 0
  x-image-meta-created_at: 2014-02-03T20:17:24
  x-image-meta-size: 505
  x-image-meta-status: active
  etag: 3a106675dfc12795963726e7b9cf53b0
  location: http://10.197.160.95:9292/v1/images/b408d525-3186-4200-a9a7-90eaf756b843
  x-image-meta-is_public: True
  x-image-meta-min_ram: 0
  x-image-meta-owner: 174a21dd0de043719d87c7c9e2f9d062
  x-image-meta-updated_at: 2014-02-03T20:17:24
  content-type: text/html; charset=UTF-8
  x-openstack-request-id: req-8413d18f-a4d1-486c-b846-f47c92b39e8e
  x-image-meta-disk_format: raw
  x-image-meta-name: testwpar
    [00m   [00;33mfrom (pid=836) log_http_response /opt/stack/python-glanceclient/glanceclient/common/http.py:152  [00m
  2014-02-21 15:46:55.121   [00;32mDEBUG nova.virt.wparrip.client [  [01;36mreq-62be8844-136e-4fe0-a431-7ecc02e87758   [00;36madmin admin  [00;32m]   [01;35m  [00;32mwparrip, pull_image=505  [00m   [00;33mfrom (pid=836) pull_image /opt/stack/nova/nova/virt/wparrip/client.py:292  [00m
  2014-02-21 15:46:55.122   [01;31mERROR nova.compute.manager [  [01;36mreq-62be8844-136e-4fe0-a431-7ecc02e87758   [00;36madmin admin  [01;31m]   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [01;31mInstance failed to spawn  [00m
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00mTraceback (most recent call last):
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/opt/stack/nova/nova/compute/manager.py", line 1434, in _spawn
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    block_device_info)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/opt/stack/nova/nova/virt/wparrip/driver.py", line 287, in spawn
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    res = self._session.pull_image(_image, context, instance['image_ref'])
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/opt/stack/nova/nova/virt/wparrip/client.py", line 307, in pull_image
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    resp = self._make_request('POST','/wparrip/api/images/pull',headers=headers, body=_get_next())
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/opt/stack/nova/nova/virt/wparrip/client.py", line 152, in _make_request
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    rest.request(*args, **kwargs)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/lib/python2.7/httplib.py", line 958, in request
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    self._send_request(method, url, body, headers)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/lib/python2.7/httplib.py", line 992, in _send_request
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    self.endheaders(body)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/lib/python2.7/httplib.py", line 954, in endheaders
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    self._send_output(message_body)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/lib/python2.7/httplib.py", line 818, in _send_output
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    self.send(message_body)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/lib/python2.7/httplib.py", line 790, in send
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    self.sock.sendall(data)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/local/lib/python2.7/dist-packages/eventlet/greenio.py", line 309, in sendall
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    tail = self.send(data, flags)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m  File "/usr/local/lib/python2.7/dist-packages/eventlet/greenio.py", line 291, in send
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m    len_data = len(data)
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00mTypeError: object of type 'generator' has no len()
    [01;31m2014-02-21 15:46:55.122 TRACE nova.compute.manager   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00m
  2014-02-21 15:46:55.124   [00;32mDEBUG nova.compute.claims [  [01;36mreq-62be8844-136e-4fe0-a431-7ecc02e87758   [00;36madmin admin  [00;32m]   [01;35m[instance: d22e3fbb-2035-4b4f-a89c-37656adc4a12]   [00;32mAborting claim: [Claim: 1 MB memory, 0 GB disk, 1 VCPUS]  [00m   [00;33mfrom (pid=836) abort /opt/stack/nova/nova/compute/claims.py:107  [00m
  2014-02-21 15:46:55.124   [00;32mDEBUG nova.openstack.common.lockutils [  [01;36mreq-62be8844-136e-4fe0-a431-7ecc02e87758   [00;36madmin admin  [00;32m]   [01;35m  [00;32mGot semaphore "compute_resources"  [00m   [00;33mfrom (pid=836) lock /opt/stack/nova/nova/openstack/common/lockutils.py:167  [00m
  </code></pre>
  
  <p>Thanks!</p>