I'm trying to storage my app flask user profile image to google cloud bucket but i'm getting a 400 bad request error.
Looking up i found this guy had the same issue as me but it doesn't help me (link)
I got a storage.py where it my upload_image_file function
from flask import current_app
from google.cloud import storage
import json
### Función que almacena las imágenes en google cloud
def upload_image_file(file, folder, contend_id):
if not file:
return None
file.format = 'png'
date = datetime.datetime.utcnow().strftime('%Y-%m-%d-%H%M%S')
filename = '{}-{}.{}'.format(contend_id, date, 'png')
client = storage.Client(project=current_app.config['PROJECT_ID'])
bucket = client.bucket(current_app.config['CLOUD_STORAGE_BUCKET'])
#blob = bucket.blob(current_app.config['GOOGLE_APPLICATION_CREDENTIALS'])
blob = bucket.blob(os.path.join(folder, filename))
blob.upload_from_string(file.read(), content_type=file.content_type)
url = blob.public.url
if isinstance(url, six.binary_type):
url = url.decode('utf-8')
return url
My controller views.py:
from flask import Blueprint, render_template, request, session, redirect, url_for, abort
from user.models import User
from user.forms import RegistrationForm, LoginForm, EditProfileForm
import bcrypt
from user.decorators import login_required
from utilities.storage import upload_image_file
user_page = Blueprint('user_page', __name__)
#Editar Usuario
@user_page.route('/edit', methods=['POST','GET'])
@login_required
def edit():
#validar que inicio sesion
user = User.objects.filter(email=session['email']).first()
if user:
error = None
message = None
form = EditProfileForm(obj=user)
#validar que los datos actualizados no esten en uso
if request.method == 'POST' and form.validate():
if user.email != form.email.data.lower():
if User.objects.filter(email=form.email.data.lower()).first():
error = 'Email is already in use'
else:
session['email'] = form.email.data.lower()
if not error:
form.populate_obj(user)
image_url = upload_image_file(request.files.get('image'), 'profile_image', str(user.id))
if image_url:
user.profile_image = image_url
user.save()
message = 'Profile updated'
return render_template('user/edit.html', user=user, form=form, error=error, message=message)
else:
abort(404)
and this is the error:
google.api_core.exceptions.BadRequest
google.api_core.exceptions.BadRequest: 400 POST https://storage.googleapis.com/upload/storage/v1/b/denunciasapp-bucket/o?uploadType=multipart: ('Request failed with status code', 400, 'Expected one of', <HTTPStatus.OK: 200>)
Traceback (most recent call last)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 1549, in upload_from_file
created_json = self._do_upload(
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 1402, in _do_upload
response = self._do_multipart_upload(
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 1092, in _do_multipart_upload
response = upload.transmit(transport, data, object_metadata, content_type)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/resumable_media/requests/upload.py", line 108, in transmit
self._process_response(response)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/resumable_media/_upload.py", line 109, in _process_response
.. _sans-I/O: https://sans-io.readthedocs.io/
"""
# Tombstone the current upload so it cannot be used again (in either
# failure or success).
self._finished = True
_helpers.require_status_code(response, (http_client.OK,), self._get_status_code)
@staticmethod
def _get_status_code(response):
"""Access the status code from an HTTP response.
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/resumable_media/_helpers.py", line 91, in require_status_code
raise common.InvalidResponse(
During handling of the above exception, another exception occurred:
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/ralphsliger/DenunciasApp/App/user/decorators.py", line 11, in decorated_function
return f(*args, **kwargs)
File "/Users/ralphsliger/DenunciasApp/App/user/views.py", line 76, in edit
image_url = upload_image_file(request.files.get('image'), 'profile_image', str(user.id))
File "/Users/ralphsliger/DenunciasApp/App/utilities/storage.py", line 20, in upload_image_file
filename = '{}-{}.{}'.format(contend_id, date, 'png')
client = storage.Client(project=current_app.config['PROJECT_ID'])
bucket = client.bucket(current_app.config['CLOUD_STORAGE_BUCKET'])
#blob = bucket.blob(current_app.config['GOOGLE_APPLICATION_CREDENTIALS'])
blob = bucket.blob(os.path.join(folder, filename))
blob.upload_from_string(file.read(), content_type=file.content_type)
url = blob.public.url
if isinstance(url, six.binary_type):
url = url.decode('utf-8')
return url
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 1716, in upload_from_string
self.upload_from_file(
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 1563, in upload_from_file
_raise_from_invalid_response(exc)
File "/Users/ralphsliger/DenunciasApp/App/env/lib/python3.8/site-packages/google/cloud/storage/blob.py", line 2612, in _raise_from_invalid_response
raise exceptions.from_http_status(response.status_code, message, response=response)
google.api_core.exceptions.BadRequest: 400 POST https://storage.googleapis.com/upload/storage/v1/b/denunciasapp-bucket/o?uploadType=multipart: ('Request failed with status code', 400, 'Expected one of', <HTTPStatus.OK: 200>)
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.
You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:
dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
I'm new using google cloud with flask i don't know what i'm missing, in that previous post i mentioned before (link) they commented that the Content Type is wrong. i don't sure why, i guided from this https://cloud.google.com/python/getting-started/using-cloud-storage