1

I want to use the google.appengine.api images package but I do not know how to install the tools for virtualenv. The package works fine when I use dev_appserver.py on my normal environment but when I use the flexible environment with flask it cannot find the package. Is there a way to add the images library into my virtualenv?

When I try using Pillow to resize the image before I uploaded it to the server but when I would do that the image would arrive in the cloud storage at 0B.

if file and allowed_file(file.filename):
    filename = '%s_%s.jpg' % (item.id, len(item.photos))
    # Resize file using pillow
    image = Image.open(file)
    image.thumbnail((300,300)
    resized_image = io.BytesIO()
    image.save(resized_image, format='JPEG')
    # if I did a image.show() here the image would 
    # properly be shown resized
    gcs = storage.Client()
    bucket = gcs.get_bucket(CLOUD_STORAGE_BUCKET)
    blob = bucket.blob(filename)

    blob.upload_from_file(resized_image,
        content_type=file.content_type)
    # I would then view the image in the bucket and it shows up as 0 bytes
    # and blank
    # If I just use the regular file it uploads fine.
nanomosfet
  • 132
  • 11
  • 1
    Can you check if `resized_image` contains what you expect? – Dan Cornilescu Jul 21 '17 at 20:42
  • 1
    Maybe `blob.upload_from_file(resized_image.get_value(),...`? – Dan Cornilescu Jul 21 '17 at 20:49
  • 1
    See also https://stackoverflow.com/questions/42800250/difference-between-open-and-io-bytesio-in-binary-streams – Dan Cornilescu Jul 21 '17 at 20:49
  • So i added this line `Image.open(resized_image).show()` and the image appears to be resized and correct. – nanomosfet Jul 21 '17 at 21:00
  • So when i use `resized_image.getvalue()` it complains that a string doesn't have a read() method. – nanomosfet Jul 21 '17 at 21:04
  • I am wondering if the request.file from flask has a special way of implementing `read()` I hope it is easier than that. – nanomosfet Jul 21 '17 at 21:25
  • 1
    Try with a real file instead of the `io.BytesIO`. If that works it's clearly a `io.BytesIO` matching issue, which is what I suspect. I can't test myself as I'm using neither flex env nor flask... – Dan Cornilescu Jul 21 '17 at 21:25
  • @DanCornilescu so I tried creating the file with `f = open('resized_image.jpg', 'w+b')` saving the file `image.save(f, format='jpeg')`, test that it shows correctly `Image.open(f).show()` which it does, but still no success. Bucket still shows that file uploaded is 0B and is not visible. Thank you so much for helping by the way. – nanomosfet Jul 21 '17 at 21:48
  • 1
    And if you call `blob.upload_from_file()` with `f`'s handle? – Dan Cornilescu Jul 21 '17 at 22:00
  • @DanCornilescu Yes I call blob.upload_from_file(f). I am thinking about just writing another route that will resize the file then post to the upload_photo handler. – nanomosfet Jul 21 '17 at 22:05
  • K, so the problem actually lies in opening and writing the blob. But I don't see it, the code seems to follow the example: https://cloud.google.com/appengine/docs/flexible/python/using-cloud-storage#application_code – Dan Cornilescu Jul 21 '17 at 22:13
  • Yeah. I have spent way too much time on this now. Thanks for the help! – nanomosfet Jul 21 '17 at 23:53
  • I will probably just use an API such as kraken.io – nanomosfet Jul 21 '17 at 23:59
  • I have raised an issue in the github repository @DanCornilescu https://github.com/GoogleCloudPlatform/google-cloud-python/issues/3655 – nanomosfet Jul 22 '17 at 01:02
  • 1
    @DanCornilescu turns out the problem was that I was not setting the file object to point back to the beginning. All i need to have was a `file_object.seek(0)` before I used the upload_from_file() method. I wrapped this in a with statement to ensure the file was deleted afterwards. – nanomosfet Jul 22 '17 at 03:05

1 Answers1

2

You may be out of luck, the images service is not available outside the standard environment.

From the Migrating Services from the Standard Environment to the Flexible Environment:

The Images service is not available outside of the standard environment. However, you can easily serve images directly from your application or directly from Cloud Storage.

If you need to do image processing, you can install and use any image processing library such as Pillow.

The Images service also provided functionality to avoid dynamic requests to your application by handling image resizing using a serving URL. If you want similar functionality, you can generate the re-sized images ahead of time and upload them to Cloud Storage for serving. Alternatively, you could use a third-party content delivery network (CDN) service that offers image resizing.

For more resources, see the following guides:

Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97
  • Thank you for your answer. You answered me it fully. I have edited the question and stated what happens when I use Pillow. Could you help with this part of the question? – nanomosfet Jul 21 '17 at 20:33