Javascript required
Skip to content Skip to sidebar Skip to footer

How to Upload Image to Google Cloud Storage Using Python

Cover image for Uploading and Downloading Zip Files In GCP Cloud Storage Using Python

Jake Witcher

Uploading and Downloading Zip Files In GCP Cloud Storage Using Python

GCP (Google Cloud Platform) cloud storage is the object storage service provided past Google for storing many data formats from PNG files to zipped source code for web apps and cloud functions. The information is stored in a flat, key/value-like data structure where the key is your storage object'south name and the value is your data.

Object storage is groovy for storing massive amounts of data every bit a single entity, data that volition later be accessed all at in one case as opposed to information that will exist read and written in small subsets as is the case with relational and not-relational databases.

If you're looking to store a collection of files as a unmarried unit, either to archive a big number of log files for hereafter audits or to bundle and store code equally a part of an automatic deployment bike, it'due south likely yous will do then by packing all of information technology together as a cipher file.

Using an awarding to automate the procedure of creating, altering, or unzipping a zip file in memory is a useful skill to have nonetheless working with memory streams and bytes rather than integers, strings, and objects can be daunting when it is unfamiliar territory.

Whether you are specifically looking to upload and download zip files to GCP deject storage or you merely take an interest in learning how to work with zilch files in memory, this postal service will walk you through the procedure of creating a new zip file from files on your local machine and uploading them to cloud storage likewise every bit downloading an existing cypher file in cloud storage and unzipping it to a local directory.

Establishing Credentials

Before you tin can begin uploading and downloading local files to cloud storage as zip files, you will demand to create the customer object used in your Python code to communicate with your project's cloud storage resources in GCP.

There are various ways to establish credentials that will grant the client object admission to a cloud storage bucket, the near mutual of which is to create a service account and assign it to your application in one of two ways.

The first choice is to assign the service account to a particular resources upon deployment. For example, if your code is being deployed as a GCP deject office, you would attach the service account to the application upon deployment using either the gcloud sdk:

                          # using powershell and the gcloud sdk to deploy a python cloud function                                          gcloud                                          functions                                          deploy                                          my-cloud-function                                          `                            --entry-point                                          my_function_name                                          `                            --runtime                                          python38                                          `                            --service-account                                          my-cloud-function              @              my-project-id.iam.gserviceaccount.com                                          `                            --trigger-http                                                  

Enter fullscreen mode Exit fullscreen mode

Or by using an IAC (infrastructure as code) solution similar Terraform:

                          resource              "google_service_account"              "my_cloud_func_sa"              {              account_id              =              "my-cloud-function"              display_name              =              "Cloud Office Service Business relationship"              }              resource              "google_project_iam_binding"              "cloud_storage_user"              {              project              =              "my-project-id"              role              =              "roles/storage.objectAdmin"              members              =              [              "serviceAccount:              ${              google_service_account              .              my_cloud_func_sa              .              e-mail              }              "              ,              ]              }              resource              "google_cloud_functions_function"              "my_cloud_func"              {              proper noun              =              "my-cloud-function"              entry_point              =              "my_function_name"              runtime              =              "python38"              service_account_email              =              google_service_account              .              my_cloud_func_sa              .              electronic mail              trigger_http              =              true              }                      

Enter fullscreen style Exit fullscreen mode

Annotation that the service account as defined in Terraform is also being referenced in a google_project_iam_binding resource equally a member that will exist assigned the role of storage.objectAdmin. You lot will need to assign a similar function (or ideally one with the minimal permissions required for your code to perform its tasks) if yous cull to create a service account using the GCP console.

For code being deployed with an assigned service account, creating the GCP deject storage client in Python requires only the project id be passed as an argument to the customer constructor.

                          from              google.cloud              import              storage              client              =              storage              .              Customer              (              project              =              GCP_PROJECT_ID              ,              )                      

Enter fullscreen mode Exit fullscreen mode

However if yous would like to upload and download to deject storage using a CLI application or to test your deject role before deploying it, you will want to use a locally stored JSON credentials file.

To create the file, open up the GCP console and select IAM & Admin from the Navigation carte, accessed through the hamburger carte du jour icon in the top left corner.

From the IAM & Admin bill of fare, select the Service Accounts page and either create a new service business relationship or click on the link of an existing one, establish under the Email column of the service accounts table.

At the lesser of the Details page for the selected service account, click Add Fundamental > Create New Key and select the JSON option.

This volition download the JSON credentials file to your machine.

Anyone with access to this file will have the credentials necessary to make changes to your cloud resources co-ordinate to the permissions of this service business relationship. Store it in a secure identify and exercise not check this file into source control. If y'all do, immediately delete the central from the aforementioned menu used to create it and remove the JSON file from source command.

To allow your client object to use these credentials and admission GCP cloud storage, initializing the client will require a few extra steps. You lot will need to create a credentials object using the from_service_account_file method on the service_account.Credentials grade of the google.oauth2 library. The just required argument for this method is the absolute or relative file path to your JSON credentials file.

This credentials object will exist passed as a second argument to the storage.Client class constructor.

                          from              google.deject              import              storage              from              google.oauth2              import              service_account              credentials              =              service_account              .              Credentials              .              from_service_account_file              (              SERVICE_ACCOUNT_FILE              )              customer              =              storage              .              Client              (              project              =              GCP_PROJECT_ID              ,              credentials              =              credentials              )                      

Enter fullscreen style Exit fullscreen fashion

Uploading Local Files to Cloud Storage as a Nix File

At present that your client object has the required permissions to access cloud storage yous can begin uploading local files as a zip file.

Assuming that the files you intend to upload are all in the same directory and are not already zipped, you will upload the files to GCP cloud storage every bit a nix file by creating a zip archive in retentivity and uploading it as bytes.

                          from              google.cloud              import              storage              from              zipfile              import              ZipFile              ,              ZipInfo              def              upload              ():              source_dir              =              pathlib              .              Path              (              SOURCE_DIRECTORY              )              archive              =              io              .              BytesIO              ()              with              ZipFile              (              archive              ,              'w'              )              every bit              zip_archive              :              for              file_path              in              source_dir              .              iterdir              ():              with              open              (              file_path              ,              'r'              )              as              file              :              zip_entry_name              =              file_path              .              proper name              zip_file              =              ZipInfo              (              zip_entry_name              )              zip_archive              .              writestr              (              zip_file              ,              file              .              read              ())              annal              .              seek              (              0              )              object_name              =              'super-important-data-v1'              bucket              =              client              .              bucket              (              BUCKET_NAME              )              hulk              =              storage              .              Hulk              (              object_name              ,              bucket              )              blob              .              upload_from_file              (              annal              ,              content_type              =              'application/zip'              )                      

Enter fullscreen mode Go out fullscreen style

io.BytesIO() creates an in retention binary stream used by the ZipFile object to shop all the data from your local files as bytes.

The files in the source directory are iterated over and for each one a ZipInfo object is created and written to the ZipFile object forth with the contents of the source file. The ZipInfo object corresponds to an private file entry inside a zip file and will be labeled with whatever file proper noun and extension you use in the constructor to instantiate the ZipInfo object. Using zip_entry_name = file_path.name every bit in the instance above volition set the file name and extension in the zippo file to match the proper noun and extension of the local file.

The in memory binary stream (the archive variable) is what you will be uploading to GCP cloud storage, nonetheless a prerequisite for uploading an in memory stream is that the stream position be gear up to the start of the stream. Without moving the position of the stream dorsum to nix with annal.seek(0) yous will go an error from the Google API when y'all try to upload the data.

With the in memory binary stream ready to be delivered, the remaining lines of lawmaking create a new Saucepan object for the specified bucket and a Blob object for the storage object. The zipped files are then uploaded to cloud storage and can later on retrieved using the storage object name you lot used to create the Blob instance.

A bucket in deject storage is a user defined partition for the logical separation of data and a blob (as the Python course is chosen) is another name for a storage object.

Downloading a Zip File Blob in Deject Storage to a Local Directory

To download a nix file storage object and unzip information technology into a local directory, yous volition need to contrary the process by starting time creating a bucket object and a blob object in order to download the nada file as bytes.

                          def              download              ():              target_dir              =              pathlib              .              Path              (              TARGET_DIRECTORY              )              object_name              =              'super-important-data-v1'              bucket              =              client              .              bucket              (              BUCKET_NAME              )              blob              =              storage              .              Blob              (              object_name              ,              bucket              )              object_bytes              =              hulk              .              download_as_bytes              ()              archive              =              io              .              BytesIO              ()              annal              .              write              (              object_bytes              )              with              ZipFile              (              archive              ,              'westward'              )              every bit              zip_archive              :              zip_archive              .              extractall              (              target_dir              )                      

Enter fullscreen manner Exit fullscreen mode

Once downloaded, the bytes tin exist written to an in retentiveness stream which will in turn be used to create a ZipFile object in guild to extract the files to your target directory. io.BytesIO() is again used to create the in memory binary stream and the write method on the BytesIO object is used to write the downloaded bytes to the stream. The ZipFile object has a method for extracting all of its contents to a specified directory, making the concluding step a uncomplicated one.

With these two functions and the appropriate credentials you should have everything yous need to start uploading and downloading your ain cypher files into cloud storage using Python.

And if y'all'd similar to run across all the Python code in one place, you can discover it here equally a Gist on my Github account.

baughancriess.blogspot.com

Source: https://dev.to/jakewitcher/uploading-and-downloading-zip-files-in-gcp-cloud-storage-using-python-2l1b