3

I am using Google's google-cloud-storage Python package for GCS access. When I get a 403 error it could be for many different reasons. Google's SDK by default only provides this message:

('Request failed with status code', 403, 'Expected one of', <HTTPStatus.OK: 200>)")

Using a debugger I can look deeper into the library and find _upload.py has a _process_response method where the true HTTP response can be found, with the following message as part of the result:

"message": "$ACCOUNT does not have storage.objects.delete access to $BLOB."

Q: Is there any way I can access this more useful error code or the raw response?

I am hoping to present to the user the difference between e.g. expired credentials and attempting to do something your credentials do not allow.

Dustin Ingram
  • 20,502
  • 7
  • 59
  • 82
Ben Page
  • 3,011
  • 4
  • 35
  • 37

1 Answers1

3

What version of google-cloud-storage are you using? With the latest, and this example:

from google.cloud import storage
client = storage.Client.from_service_account_json('service-account.json')
bucket = client.get_bucket('my-bucket-name')
blob = bucket.get_blob('test.txt')
try:
    blob.delete()
except Exception as e:
    print(e)

It prints the following:

403 DELETE https://storage.googleapis.com/storage/v1/b/my-bucket-name/o/test.txt?generation=1579627133414449: $ACCOUNT does not have storage.objects.delete access to my-bucket-name/test.txt.

The string representation here is roughly the same as e.message:

>>> e.message
'DELETE https://storage.googleapis.com/storage/v1/b/my-bucket-name/o/test.txt?generation=1579627133414449: $ACCOUNT does not have storage.objects.delete access to my-bucket-name/test.txt.'

If you want more structure, you can use e._response.json():

>>> e._response.json()
{
    'error': {
        'code': 403,
        'message': '$ACCOUNT does not have storage.objects.delete access to my-bucket-name/test.txt/test.txt.',
        'errors': [{
            'message': '$ACCOUNT does not have storage.objects.delete access to my-bucket-name/test.txt/test.txt.',
            'domain': 'global',
            'reason': 'forbidden'
        }]
    }
}
Dustin Ingram
  • 20,502
  • 7
  • 59
  • 82