Write a CSV to store in Google Cloud Storage
<p>Background: I'm taking data in my Python/AppEngine project and creating a .tsv file so that I can create charts with d3.js.  Right now I'm writing the CSV with each page load; I want to instead store the file once in Google Cloud Storage and read it from there.</p>

<p>How I'm currently writing the file, each time the page is loaded!:</p>

<pre><code>def get(self):  ## this gets called when loading myfile.tsv from d3.js
    datalist = MyEntity.all()
    self.response.headers['Content-Type'] = 'text/csv'
    writer = csv.writer(self.response.out, delimiter='\t')
    writer.writerow(['field1', 'field2'])
    for eachco in datalist:
        writer.writerow([eachco.variable1, eachco.variable2])
</code></pre>

<p>And while inefficient, this is working just fine.</p>

<p>Using <a href="https://cloud.google.com/appengine/docs/python/googlecloudstorageclient/read-write-to-cloud-storage" rel="nofollow">this Google Cloud Storage documentation</a>, I've been trying to get something like this working:</p>

<pre><code>def get(self):
    filename = '/bucket/myfile.tsv'
    datalist = MyEntity.all()
    bucket_name = os.environ.get('BUCKET_NAME', app_identity.get_default_gcs_bucket_name())
    write_retry_params = gcs.RetryParams(backoff_factor=1.1)
    writer = csv.writer(self.response.out, delimiter='\t')
    gcs_file = gcs.open(filename, 'w', content_type='text/csv', retry_params=write_retry_params)
    gcs_file.write(writer.writerow(['field1', 'field2']))
    for eachco in datalist:
        gcs_file.write(writer.writerow([eachco.variable1, eachco.variable2]))
    gcs_file.close()
</code></pre>

<p>But I'm getting:</p>

<pre><code>TypeError: Expected str but got &lt;type 'NoneType'&gt;.
</code></pre>

<p>I thought that the output of csv.writer would be a string, so I'm not sure why I'm getting the TypeError.</p>

<p>So I can think of two situations:</p>

<ol>
<li>I've got something screwed up in my code that writes the tsv to
Cloud Storage.  It should be simple to iterate through and write a TSV/CSV file to Cloud Storage though, right?</li>
<li>I've gone about this the completely wrong way
entirely, and should maybe even use BlobStore or db.TextProperty()
to store this .tsv data.  (The files aren't that big; definitely
well under 1MB)</li>
</ol>

<p>I'd appreciate any help!</p>

<p><strong>edit - full traceback</strong></p>

<pre><code>Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/mydirectory/myapp/handlers.py", line 21, in dispatch
    webapp2.RequestHandler.dispatch(self)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/mydirectory/myapp/thisapp.py", line 384, in get
    gcs_file.write(writer.writerow(['field1', 'field2']))
  File "lib/cloudstorage/storage_api.py", line 754, in write
    raise TypeError('Expected str but got %s.' % type(data))
TypeError: Expected str but got &lt;type 'NoneType'&gt;.
</code></pre>

<p>The problem is that <code>writer.writerow</code> doesn't return anything. The return type will be <code>None</code>, and you are trying to write that into <code>gcs_file</code>.</p>

python csv google-app-engine google-cloud-storage