3
votes

API that allows to write files into blobstore pragmatically now deprecated and will be removed in the future. But I'm using this API to save user pictures from external services. I can't use upload handler to do this.

Is there is any alternative way to write files directly into blobstore when Files API will be removed?

https://developers.google.com/appengine/docs/python/blobstore/#Writing_Files_to_the_Blobstore

1
What about the note there in the red box confuses you? Writing to the blobstore is deprecated, you should write to Cloud Storage instead. - Daniel Roseman
I do not want to use an additional library. (GCS) - Dmytro Sadovnychyi
You don't have much of a choice. - Linuxios

1 Answers

2
votes

Here's an example that solves my problem. Now we can upload files programmatically avoiding deprecated Files API.

class BlobstoreUpload(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('file')
    blob_info = upload_files[0]
    return self.response.write(blob_info.key())

  @classmethod
  def encode_multipart_formdata(cls, fields, files, mimetype='image/png'):
    """
    Args:
      fields: A sequence of (name, value) elements for regular form fields.
      files: A sequence of (name, filename, value) elements for data to be
        uploaded as files.

    Returns:
      A sequence of (content_type, body) ready for urlfetch.
    """
    boundary = 'paLp12Buasdasd40tcxAp97curasdaSt40bqweastfarcUNIQUE_STRING'
    crlf = '\r\n'
    line = []
    for (key, value) in fields:
      line.append('--' + boundary)
      line.append('Content-Disposition: form-data; name="%s"' % key)
      line.append('')
      line.append(value)
    for (key, filename, value) in files:
      line.append('--' + boundary)
      line.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
      line.append('Content-Type: %s' % mimetype)
      line.append('')
      line.append(value)
    line.append('--%s--' % boundary)
    line.append('')
    body = crlf.join(line)
    content_type = 'multipart/form-data; boundary=%s' % boundary
    return content_type, body


class UserProfile(webapp2.RequestHandler):
  def post(self):
    picture = self.request.POST.get('picture')

    # Write new picture to blob
    content_type, body = BlobstoreUpload.encode_multipart_formdata(
      [], [('file', name, image)])
    response = urlfetch.fetch(
      url=blobstore.create_upload_url(self.uri_for('blobstore-upload')),
      payload=body,
      method=urlfetch.POST,
      headers={'Content-Type': content_type},
      deadline=30
    )
    blob_key = response.content