1

I'm making a web app where you can both upload and download files but I'm hosting it on Heroku so I couldn't store the files on my computer. I decided to use something called Flask-GoogleStorage but it required a "Google Cloud Storage Client." I went to the cloud console and made a service account and put the private key in my code but I keep on getting this error:

[2022-01-03 19:54:20,784] WARNING in google_storage: Could not authenticate the Google Cloud Storage client

Here is my code I'm using to setup the storage:

app.config['GOOGLE_APPLICATION_CREDENTIALS'] = PRIVATE_SERVICE_KEY
app.config['GOOGLE_STORAGE_LOCAL_DEST'] = UPLOAD_FOLDER
app.config['SERVER_NAME'] = SERVER_NAME
#Google cloud storage
with app.app_context():
    files = Bucket("files")
    storage = GoogleStorage(files)
    app.config.update(
        GOOGLE_STORAGE_LOCAL_DEST = app.instance_path,
        GOOGLE_STORAGE_SIGNATURE = {"expiration": timedelta(minutes=5)},
        GOOGLE_STORAGE_FILES_BUCKET = "files-bucket-id"
    )
    storage.init_app(app)

Any advice would be super helpful as I haven't used this google platform before and I'm quite lost.

If there's any easier way to store files online, I would also greatly appreciate knowing about that.

Thank you in advance!

OmikronII
  • 35
  • 7
  • I've not used `Flask-GoogleStorage` but I'm familiar with GCP and Cloud Storage. When you created the Service Account, did you assign it suitable permissions (perhaps, for testing, `roles/storage.admin`). Did you create a storage Bucket? Bucket name must be *globally* unique. If `files` corresponds to a Bucket name, you should choose something else, perhaps `omikronII-220103-files`. The difference between `files` and `files-bucket-id` are unclear from the documentation. – DazWilkin Jan 04 '22 at 01:48
  • One thing, you will probably need to `export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/key.json` **before** you run Flask. – DazWilkin Jan 04 '22 at 01:59

1 Answers1

1

Ok, I think I understand what you need to do.

You will need to install Cloud SDK (gcloud) to follow these instructions but you can also do everything using Google's Cloud Console:

BILLING=[[YOUR-BILLING-ACCOUNT]]
PROJECT=[[YOUR-PROJECT]]
BUCKET=[[YOUR-BUCKET]]
ACCOUNT=[[YOUR-SERVICE-ACCOUNT]]

# Create Project
gcloud projects create ${PROJECT}

# Associate Billing required for Cloud Storage
gcloud beta billing projects link ${PROJECT} \
--billing-account=${BILLING}

# Create Bucket
gsutil mb -p ${PROJECT} gs://${BUCKET}

# Create Service Account
gcloud iam service-accounts create ${ACCOUNT} \
--project=${PROJECT}

EMAIL=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com

# Grant Service Account permission to Cloud Storage
gcloud projects add-iam-policy-binding ${PROJECT} \
--role=roles/storage.admin \
--member=serviceAccount:${EMAIL}

# Create Service Account Key
gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
--iam-account=${EMAIL} \
--project=${PROJECT}

# Export
export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json

flask run

And (replace [[VARIABLES]] with values):

from flask_googlestorage import GoogleStorage, Bucket

files = Bucket("files")
storage = GoogleStorage(files)

app = Flask(__name__)
app.config.update(
    GOOGLE_STORAGE_LOCAL_DEST = app.instance_path,
    GOOGLE_STORAGE_SIGNATURE = {"expiration": timedelta(minutes=5)},
    GOOGLE_STORAGE_FILES_BUCKET = "[[BUCKET]]"
)
storage.init_app(app)
DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • This seems super useful thank you! I'm a little busy right now but I'll try and implement it by the end of today and I'll let you know if it works – OmikronII Jan 04 '22 at 03:40