Reputation: 941
I'm trying to upload some images to GCS via an App Engine instance using Flask, but every time the file it's uploaded, when I download it I get a corrupt file. What am I doing wrong ?
I've downloaded and used the Google Cloud Storage client the way is in the docs.
@app.route('/upload', methods=['POST'])
def upload():
if request.method == 'POST':
file = request.files['file']
extension = secure_filename(file.filename).rsplit('.', 1)[1]
options = {}
options['retry_params'] = gcs.RetryParams(backoff_factor=1.1)
options['content_type'] = 'image/' + extension
bucket_name = "gcs-tester-app"
path = '/' + bucket_name + '/' + str(secure_filename(file.filename))
if file and allowed_file(file.filename):
try:
with gcs.open(path, 'w', **options) as f:
f.write(str(file))
print jsonify({"success": True})
return jsonify({"success": True})
except Exception as e:
logging.exception(e)
return jsonify({"success": False})
Thanks for your help !!
Upvotes: 5
Views: 8271
Reputation: 2881
You're uploading (writing to the gcs stream) the str representation of the file object, not the file contents.
try this:
@app.route('/upload', methods=['POST'])
def upload():
if request.method == 'POST':
file = request.files['file']
extension = secure_filename(file.filename).rsplit('.', 1)[1]
options = {}
options['retry_params'] = gcs.RetryParams(backoff_factor=1.1)
options['content_type'] = 'image/' + extension
bucket_name = "gcs-tester-app"
path = '/' + bucket_name + '/' + str(secure_filename(file.filename))
if file and allowed_file(file.filename):
try:
with gcs.open(path, 'w', **options) as f:
f.write(file.stream.read())# instead of f.write(str(file))
print jsonify({"success": True})
return jsonify({"success": True})
except Exception as e:
logging.exception(e)
return jsonify({"success": False})
But this is not the most efficient way to do this, also, there is a 32mb cap on file uploads straight from app engine, the way to avoid this is by signing an upload url with GCS and upload the file directly from the front-end to GCS, or you can create a file upload url with blobstore and a handler to do the post-upload processing, as specified here: https://cloud.google.com/appengine/docs/python/blobstore/
Upvotes: 9