Domanda

I've got a process that fetches an image from a given URL and saves it to Google Cloud Storage and retrieves a serving url. Now, my understanding (from the documentation I've read) is that I must also create a blob in the process that references the GCS file. If my understanding is incorrect, please let me know.

The handler that fetches the image and tries to save it is:

img_request = urlfetch.fetch(img_url)
    if img_request.status_code == 200:
        img_title               = hashlib.sha1(img_url).hexdigest()
        img_content             = img_request.content
        img_type                = img_request.headers['content-type']
        cloud_storage_filename  = '/images/%s/%s' % (self.source_name, img_title)

        blobstore_filename      = '/gs%s' % cloud_storage_filename
        blobstore_key           = blobstore.create_gs_key(blobstore_filename)

        cloud_storage_file      = gcs.open(filename=cloud_storage_filename, mode='w', content_type=img_type)
        cloud_storage_file.write(img_content)
        cloud_storage_file.close()

        # If I print blobstore_key at this stage, I am getting a result here.
        blobstore_key           = blobstore.get(blobstore_key).key()
        blobstore_serving_url   = images.get_serving_url(blobstore_key)

        # Structured Property to be part of a Datastore Model
        img_model = data_model.Image(
            s_source_url    = img_url,
            k_blob_key      = blobstore_key,
            s_serving_url   = blobstore_serving_url
        )
        return img_model

This works fine on the dev_appserver, however, in production it raises the following error:

   blobstore_key           = blobstore.get(blobstore_key).key()
   AttributeError: 'NoneType' object has no attribute 'key'

Why is this error being raised in Production and not on the dev_appserver? As if the key is not being generated in the first place...

As I have commented in the code, when I print the blobstore_key before calling blobstore.get(blobstore_key).key(), it does print out a key, so it's working fin until there. The problem is, presumably, when I call blobstore.get() on the key, it gets None... why???

Or am I doing something completely wrong? Thanks!

È stato utile?

Soluzione 2

Solved.

Substituted:

blobstore_key = blobstore.create_gs_key(blobstore_filename)

With:

blobstore_key = blobstore.BlobKey(blobstore_key)

Altri suggerimenti

blobstore.get() is a synonym for BlobInfo.get(), and a note on this page says:

However, BlobInfo objects are currently not available for GCS objects.

This would explain why your blobstore.get() returns None.

Also, aren't you expecting to receive the same result from these two lines?

blobstore_key = blobstore.create_gs_key(blobstore_filename)
blobstore_key = blobstore.get(blobstore_key).key()

BlobInfo object from a BlobKey created using blobstore.create_gs_key seems to partially answer my doubts of why it does not work in production. However, how do I get the servng_url for a image then?

It sucks that GAE has different behaviours when using blobInfo in local mode or the production environment, it took me a while to find out that, but a easy solution is that:

You can use a blobReader to access the data when you have the blob_key

def getBlob(blob_key):
  logging.info('getting blob('+blob_key+')')

  with blobstore.BlobReader(blob_key) as f:
    data_list = []
    chunk = f.read(1000)
    while chunk != "":
      data_list.append(chunk)
      chunk = f.read(1000)

    data = "".join(data_list)

  return data`

https://developers.google.com/appengine/docs/python/blobstore/blobreaderclass

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top