OmikronII
OmikronII

Reputation: 35

Flask: How to upload a user file into Google Cloud Storage using upload_blob

I'm using Flask to make a web application and I want to upload a user input file to Google Storage Cloud. I'm using Heroku to host my web app and I don't know how to save files on Heroku's temporary storage so I'm trying to use tempfile to store the file in a directory and then access the directory to upload the file.

When I try to do that, I get this error: PermissionError: [Errno 13] Permission denied: 'C:\\Users\\[MyName]\\AppData\\Local\\Temp\\tmpbpom7ull'

Here is my code I'm working with, if anyone has any other way to upload a FileStorage object to the Google Storage cloud or a way to access the saved file, that would be very appreciated!

# File is currently a "FileStorage" object from werkzeug, gotten by doing
# file = request.files["filename"]
tempdir = tempfile.mkdtemp()
file.name = filename
file.save(tempdir)

upload_blob(BUCKET_NAME,filename,filename)

Upvotes: 0

Views: 1483

Answers (2)

DazWilkin
DazWilkin

Reputation: 40261

Following up on yesterday's Flask: Could not authenticate question the Google Cloud Storage client, you can use werkzeug's FileStorage object as described in the Flask-GoogleStorage usage:

Assuming you a have a file hellofreddie.txt in the working directory:

hellofreddie.txt:

Hello Freddie!

You can then open it, create a FileStorage object and then use the save on Bucket object (files):

from datetime import timedelta

from flask import Flask
from flask_googlestorage import GoogleStorage, Bucket
from werkzeug.datastructures import FileStorage

import os


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 = os.getenv("BUCKET")
)
storage.init_app(app)

with app.app_context():
    with open("hellofreddie.txt","rb") as f:
        file = FileStorage(f)
        filename = files.save(file)

After the code has run, you will see a UUID-named equivalent created in Cloud Storage.

You can use the storage browser or gsutil:

gsutil ls gs://${BUCKET}
gs://{BUCKET}/361ea9ea-5599-4ff2-84d1-3fe1a802ac08.txt

NOTE I was unable to resolve an issue trying to print either files.url(filename) or files.signed_url(filename). These methods correctly return the Cloud Storage Object but as PurePosixPath('f3745268-5c95-4c61-a892-09c0de556635.txt'). My Python naivete.

Upvotes: 3

OmikronII
OmikronII

Reputation: 35

I've realized my error, I was trying to use file.save() to a folder and not to an actual file, my code has been updated to

tempdir = tempfile.mkdtemp()
    file.name = filename
    file.save(tempdir + "/" + filename)

    upload_blob(BUCKET_NAME,tempdir + "/" + filename,filename)

Thank you to PermissionError: [Errno 13] Permission denied

Upvotes: 1

Related Questions