googleapis / google-cloud-python

Google Cloud Client Library for Python
https://googleapis.github.io/google-cloud-python/
Apache License 2.0
4.8k stars 1.51k forks source link

Get Serving URL for images stored in Storage (Similar to App Engine Image Class) #1295

Closed saxenanurag closed 8 years ago

saxenanurag commented 8 years ago

Would it be possible to get something similar to get_serving_url in app engine (https://cloud.google.com/appengine/docs/python/refdocs/google.appengine.api.images#google.appengine.api.images.get_serving_url) using this library as well? Thanks.

dhermes commented 8 years ago

Thanks @saxenanurag, you can already do this to some degree:

from gcloud import storage
client = storage.Client()  # Implicit environ set-up
bucket = client.bucket('my-bucket')
blob = bucket.blob('my-blob')
url_lifetime = 3600  # Seconds in an hour
serving_url = blob.generate_signed_url(url_lifetime)

I'm going to close this out, but if you think this doesn't meet your needs, I'm happy to re-open and discuss.

saxenanurag commented 8 years ago

Does this mean that the link expires in 3600 seconds? Thanks.

dhermes commented 8 years ago

Yes it does. Your other alternative is to use the publicRead ACL: https://cloud.google.com/storage/docs/access-control

and then there is a Blob.public_url property to use.

saxenanurag commented 8 years ago

That is not what get_serving url does. Here is the quote from the app engine documentation:

Using get_serving_url() allows you to dynamically resize and crop images, so you don't need to store different image sizes on the server. This method returns a URL that serves the image, and transformations to the image are encoded in this URL.

https://cloud.google.com/appengine/docs/python/images/

I am working on a project that is currently on App Engine. We are moving it to Compute Engine but are still using Cloud Storage for static file storage. get_serving_url helped in serving images in multiple sizes, without giving away the folder structure of the storage.

dhermes commented 8 years ago

Actually doing the resizing is a feature of App Engine that isn't present in the Cloud Storage API. This library simply offers the API methods (and tries to make them helpful and useful). Resizing images goes outside that scope, sorry.

dhermes commented 8 years ago

@jgeewax Do you know if there is any Cloud API (outside of GAE) that can do resizing and serving on the fly?

robin-anil commented 8 years ago

+1 would love to see get_serving_url functionality come to google cloud storage api.

jgeewax commented 8 years ago

So... I'm just gonna leave this here.... https://gist.github.com/carlo/5379498

robin-anil commented 8 years ago

Thats a great tip @jgeewax However we don't want this to be taken down from under us, we are looking for a serious SLA on this one. We have had issues with various beta apis breaking and causing production issues. I am a Xoogler and remembers how bad Google used to be at keeping API. So forgive my caution.

I would really like Google to provide a public API for this and hope this comes with standard Google cloud storage api, since we have the originals in cloudstorage.

theacodes commented 8 years ago

@r-tock if you need something production-ready, I would highly recommend that you generate all of the sizes you need ahead-of-time.

You can even write a small App Engine application that listens for object uploads and then generates the resized versions using PIL and uploads them.

jgeewax commented 8 years ago

Yea, that's completely unofficial.

AFAIK, we don't have an API for dealing with images that way. The best route to go is probably a mini GAE app as @jonparrott said.

robin-anil commented 8 years ago

@jonparrott @jgeewax I am doing exactly that, I have a mini App engine app which return the serving url from any of our internal buckets.

Given that this Api does not work on the new Managed container runtime, I am worried about the future of that API as well. That is why I would like it to be ported to either the new Managed container runtime or directly in the Google storage api.

theacodes commented 8 years ago

@r-tock I do not know any details on the future of the Images API but in the event of any deprecation we have a 1-year deprecation policy as stated in our terms of service.

In terms of APIs available in the Flexible runtime - please keep in mind that Flexible is in beta and features may be added or removed. In general we're trying to make most APIs available from anywhere like we have done with Cloud Datastore.

As I mentioned, if you want to truly remove dependence on that API then I'd recommend having your small App Engine app generate the size ahead-of-time instead of producing a serving URL.

robin-anil commented 8 years ago

/ack about pre-resizing.

Would still like if Gcloud team can reconsider providing an on-the fly resizing service. We would love to do dynamic resizing based on the client device info and having an on-the-fly service make the implementation easier for responsive mobile apps.

theacodes commented 8 years ago

@jgeewax and I can give that feedback internally, but it's not up to this client library to provide that service - they just provide this client library, not the services themselves.

Thanks for the feedback, and let us know if there's anything else we can do.

robin-anil commented 8 years ago

Adding to that. This is something our designers would like and they always keep pointing to services like https://www.imgix.com/ which does this and question why we are using Google cloud when other services provide simpler interface.

Google should make its infrastructure simpler for common product use cases given we are already paying for Google infra, and it would be faster to load from Google cloud than from any other service if Google can match those simple features.

Thanks for the soapbox :)

GabiAxel commented 7 years ago

I opened an issue for this in App Engine: https://code.google.com/p/googleappengine/issues/detail?id=13404

May be worth starring.

DrMatthewDunn commented 7 years ago

+1 on get_serving_url. FWIW - images.Image transforms DO work on Cloud Storage objects, so manufacturing needed-size copies on the fly (then storing the copies on CS) is feasible.

Beyond that - if you really need dynamic transformations, take a look at Cloudinary, specifically 'fetch remote images', to get on the fly handling of images in your CS bucket.

laanlabs commented 7 years ago

+1 on get_serving_url.

o-alexandrov commented 7 years ago

+1

mitchellhuang commented 7 years ago

+1

proserve commented 6 years ago

+1

savraj commented 6 years ago

Guys, this works right now -- the get_serving_url functionality works for me on the dev server and will try on production soon. Here's how you do it -- you call get_serving_url like this:

get_serving_url(None, filename="/gs/mybucket/myfile.jpg")

reco commented 6 years ago

@savraj can you do resizing on the fly by adding =s200 to your serving url?

savraj commented 6 years ago

yes I believe so, though I haven't thought about this in years :)

ShaMan123 commented 6 years ago

@savraj could you provide a git repo with code? I'm having a hard time trying to get this work

ShaMan123 commented 6 years ago

+1

asciimike commented 6 years ago

@ShaMan123, I have a minimal example of Python + Image Serving below:

# main.py
# Generates a GAE Images API serving URL from a file in GCS
# Change <your_bucket_name>
from google.appengine.api import images
from google.appengine.ext import blobstore
import webapp2
class MainPage(webapp2.RequestHandler):
    def get(self):
        file = self.request.get('file')
        gs = "/gs/{0}/{1}".format('<your_bucket_name>', file)
        blob_key = blobstore.create_gs_key(gs)
        url = images.get_serving_url(blob_key, size=150, crop=True, secure_url=True)
        self.response.write(url)
app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

# Get a serving URL using your app (note that the file must already be in the GCS bucket, you can simply use the Cloud Console to do this)
$ curl "https://<your-app-name>.appspot.com/?file=<some_file_name.jpg>"
> https://lh3.googleusercontent.com/<some_long_string>=s150-c

That said, given that Imgix now supports GCS buckets as object sources, I'd strongly recommend taking a look at it.

ShaMan123 commented 6 years ago

thanks! didn't work for me but I found a workaround

On 13 April 2018 at 18:58, Michael McDonald notifications@github.com wrote:

@ShaMan123 https://github.com/ShaMan123, I have a minimal example of Python + Image Serving below:

main.py

Generates a GAE Images API serving URL from a file in GCS

Change

from google.appengine.api import images from google.appengine.ext import blobstore import webapp2 class MainPage(webapp2.RequestHandler): def get(self): file = self.request.get('file') gs = "/gs/{0}/{1}".format('', file) blob_key = blobstore.create_gs_key(gs) url = images.get_serving_url(blob_key, size=150, crop=True, secure_url=True) self.response.write(url) app = webapp2.WSGIApplication([ ('/', MainPage), ], debug=True)

Get a serving URL using your app (note that the file must already be in the GCS bucket, you can simply use the Cloud Console to do this)

$ curl "https://.appspot.com/?file="

https://lh3.googleusercontent.com/=s150-c

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/GoogleCloudPlatform/google-cloud-python/issues/1295#issuecomment-381181305, or mute the thread https://github.com/notifications/unsubscribe-auth/AgwLceuhdkP6Lo15UKPm5Qrm3FTRbMZvks5toMs2gaJpZM4G21Kj .

hamx0r commented 6 years ago

One can actually set the blobkey arg to None and then use the filename kwarg to your file path prepended by /gs like this: images.get_serving_url(None, filename='/gs{}'.format(filename))

filename would be like /mybucket/some/path/to/photo.jpg

In other words, there's no need to use the blobstore.create_gs_key() function as an intermediate step.

sbudhram commented 3 years ago

@ShaMan123 What was your workaround for this issue? I can't get this to work either.

ShaMan123 commented 3 years ago

@sbudhram Sorry I don't remember 🤔 and I think this method has been deprecated. But there's getSignedUrl exposed in @google-cloud/storage. Maybe it'll help. Take a look: https://cloud.google.com/storage/docs/access-control/signed-urls https://googleapis.dev/nodejs/storage/latest/Bucket.html#getSignedUrl https://cloud.google.com/storage/docs/access-control/signing-urls-manually