1
votes

Trying to access google cloud storage bucket from inside google app engine standard running flask using the client library for Python .

(edit) not officially supported. see answer for workaround.

code looks something like this..

from flask import Flask
from google.cloud import storage

# UNCOMMENT THIS FOR SOLUTION
#import requests_toolbelt.adapters.appengine
#requests_toolbelt.adapters.appengine.monkeypatch()

app = Flask(__name__)
@app.route('/endpoint', methods=['POST', 'PUT'])
def upload_to_storage():
    try:

      # file info
      filename = secure_filename(file.filename)
      mimetype = file.content_type

      # connect to bucket
      client = storage.Client(project='projectName')
      bucket = client.get_bucket('bucketName')

      # upload file to bucket
      blob = storage.Blob(filename, bucket)
      blob.upload_from_file(file, content_type=mimetype, num_retries=10)

      return jsonify({'status':200})

    except:

      return jsonify({'status':500})

error message:

('Connection aborted.', error(13, 'Permission denied'))

2
App engine apps run as a particular service account. Does your app engine app's service account have permission to do stuff with the bucket 'my-bucket'?Brandon Yarbrough
yep, service account has permission. I think what was happening was I needed to make sure Requests uses URLFetch cloud.google.com/appengine/docs/standard/python/issue-requestsSam Murphy

2 Answers

2
votes

Answer

(edit) google.cloud.storage is not officially supported in GAE standard, to get authentication to work (google-auth) need to do a few extra steps:

update requirements.txt

requests-toolbelt

assuming you are using a directory called 'lib' to vendor in 3rd party libraries

$ pip install -r requirements.txt -t lib

update appengine_config.py from google.appengine.ext import vendor vendor.add('lib')

update main.py (or equivalent) import requests_toolbelt.adapters.appengine requests_toolbelt.adapters.appengine.monkeypatch()

update app.yaml libraries: - name: ssl version: latest

1
votes

Instead of using the google.cloud.storage modules, use the GCS client designed specifically for operating within GAE standard: https://cloud.google.com/appengine/docs/standard/python/googlecloudstorageclient/setting-up-cloud-storage#downloading_the_client_library. This client will implicitly perform the authentication avoiding that 'Permission denied' error.

The following page demonstrates how to write using the client: https://cloud.google.com/appengine/docs/standard/python/googlecloudstorageclient/read-write-to-cloud-storage#writing_to_cloud_storage. The only missing information is that the "filename" in the example is in the format "//". The write operation takes care of locating and writing to the correct bucket(You do not need to retrieve the bucket beforehand).