I'm currently working on a project running flask on the Appengine standard environment, and I'm attempting to serve an image that has been uploaded onto Google Cloud Storage on my project's default Appengine storage bucket.
This is the routing code I currently have:
# main.py
from google.appengine.api import images
from flask import Flask, send_file
app = Flask(__name__)
...
@app.route("/sample_route")
def sample_handler():
myphoto = images.Image(filename="/gs/myappname.appspot.com/mysamplefolder/photo.jpg")
return send_file(myphoto)
...
However, I am getting an AttributeError: 'Image' object has no attribute 'read'
error.
The question is, how do I serve an image sourced from google cloud storage using an arbitrary route using python and flask?
EDIT:
I am actually trying to serve an image that I have uploaded to the default Cloud Storage Bucket in my app engine project.
I've also tried to serve the image using the following code without success:
# main.py
from google.appengine.api import images
from flask import Flask, send_file
app = Flask(__name__)
...
@app.route("/sample_route")
def sample_handler():
import cloudstorage as gcs
gcs_file = gcs.open("/mybucketname/mysamplefolder/photo.jpg")
img = gcs_file.read()
gcs_file.close()
return send_file(img, mimetype='image/jpeg')
...
I've used the GoogleAppEngineCloudStorageClient
Python library and loaded images with code similar to the following example:
from google.appengine.api import app_identity
import cloudstorage
from flask import Flask, send_file
import io, os
app = Flask(__name__)
# ...
@app.route('/imagetest')
def test_image():
# Use BUCKET_NAME or the project default bucket.
BUCKET_NAME = '/' + os.environ.get('MY_BUCKET_NAME',
app_identity.get_default_gcs_bucket_name())
filename = 'mytestimage.jpg'
file = os.path.join(BUCKET_NAME, filename)
gcs_file = cloudstorage.open(file)
contents = gcs_file.read()
gcs_file.close()
return send_file(io.BytesIO(contents),
mimetype='image/jpeg')
Using google-cloud-storage==1.6.0
from flask import current_app as app, send_file, abort
from google.cloud import storage
import tempfile
@app.route('/blobproxy/<filename>', methods=['GET'])
def get(filename):
if filename:
client = storage.Client()
bucket = client.get_bucket('yourbucketname')
blob = bucket.blob(filename)
with tempfile.NamedTemporaryFile() as temp:
blob.download_to_filename(temp.name)
return send_file(temp.name, attachment_filename=filename)
else:
abort(400)
I recommend looking at the docs for the path
or string
converters for your route, and NamedTemporaryFile
defaults to delete=True
so no residue.
flask
also figures out the mimetype
if you give it a file name, as is the case here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With