I have an older (Python 2.7) Google App Engine app that I recently deployed using Google Cloud Platform (gcloud), since appcfg was retired. I'm having issues using the images.get_serving_url not working for uploaded image blobs. The Images API is returning 'TransformationError'. This code worked previously for years in production before the switch to google cloud platform.
One quick thing to note is that Google Cloud Platform created a default storage bucket for blobs. Previously, I think GAE was using the Blobstore, so even though this change is transparent to developers, probably a lot has happened under the hood. I think for some reason my app is having issues creating the image url for the file stored on the cloud storage bucket.
I made a very simple test case to replicate the issue. Are there new requirements, or should this work?
class testUpload(webapp.RequestHandler):
def get(self):
uploadUrl = blobstore.create_upload_url('/testUploadHandler')
print("Generated upload url: %s" % uploadUrl)
self.response.out.write("""
<html><body>
<form action="{0}" method="POST" enctype="multipart/form-data">
Upload File: <input type="file" name="file"><br>
<input type="submit" name="submit" value="Submit">
</form>
</body></html>""".format(uploadUrl))
class testUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
logging.info("testUploadHandler called.")
upload = self.get_uploads()[0]
blob_key = upload.key()
image_url = images.get_serving_url(blob_key)
self.redirect(image_url)
The deployed code returns the following error on the web server (local dev server is fine):
Traceback (most recent call last):
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s~puzzleflow-dev/20210325t013659.433969250928848570/puzzleflow.py", line 4171, in post
image_url = images.get_serving_url(blob_key)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/1/google/appengine/api/images/__init__.py", line 1866, in get_serving_url
return rpc.get_result()
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 615, in get_result
return self.__get_result_hook(self)
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/fdc6d631da52d25b/python27/python27_lib/versions/1/google/appengine/api/images/__init__.py", line 1970, in get_serving_url_hook
raise _ToImagesError(e, readable_blob_key)
TransformationError
Also, you can try this yourself by going to this link (it should be publicly available):
The issue was that I had switched my access control to Uniform, since Google says this is the 'recommended' setting. I'm not well-versed enough on the differences between Fine-Grained and Uniform, but switching it back to Fine-Grained fixed the problem.