はじめに

この記事では、Googleが公式で用意しているクライアントライブラリの1つであるPythonのgoogle-cloud-storageライブラリを使用して、Google Colaboratory上でCloud Storageを操作する方法を説明します。

この記事のコードサンプルはこちらから実行できます。

クライアントライブラリ

Google Cloud のクライアントライブラリは、さまざまなプログラミング言語で Google Cloud のサービスを簡単に利用できるようにするためのライブラリです。各プログラミング言語の慣習に沿って設計されているため、開発者は自然なコードで Cloud API を呼び出すことができます。また、REST/HTTP API を直接呼び出す際の、認証、リトライ、ページネーションといった煩雑な処理をライブラリが内部で処理してくれます。

Cloud Storageを操作する

サービスアカウントキーの作成

Google Cloudコンソールの左サイドメニューからAPIとサービス>認証情報を選択

画面下のサービスアカウントの項目の右端にある「サービスアカウントを管理」をクリック

サービスアカウントのページに遷移するので、「+ サービスアカウントを作成」をクリック

サービスアカウント名、サービスアカウントID、サービスアカウントの説明を記入し、「作成して続行」をクリック

権限には、ストレージ管理者を指定して「続行」をクリック

アクセス権を持つプリンシパルは何も指定せず「完了」をクリック

サービスアカウントが作成されるので、右の「操作」から、「鍵を管理」をクリック

鍵のページに遷移するので、「キーを追加」から、「新しい鍵を追加」をクリック

キーのタイプでJSONを選択し、「作成」をクリック

前準備

ファイルのアップロード

左のサイドメニューのファイルから、サービスアカウントキーと任意のpng画像を、それぞれ、service_account_key.jsonと、sample.pngという名称でアップロードします。

ライブラリのインストール

!pip install google-cloud-storage

環境変数の設定

import os
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = [サービスアカウントキー(JSONファイル)へのパス]

環境変数GOOGLE_APPLICATION_CREDENTIALSにサービスアカウントキーのパスを設定します。

クライアントの作成

from google.cloud import storage
storage_client = storage.Client()

クライアントを作成します。
認証には、環境変数`GOOGLE_APPLICATION_CREDENTIALS`に設定されたサービスアカウントキーが使用されます。後続のGCS操作のエントリーポイントとなります。

バケット操作

import datetime

timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
BUCKET_NAME = f"sample_bucket_{timestamp}"

以降の操作では、ここで定義したバケット名を使用します。 グローバルで一意の制約があるためバケット名にタイムスタンプを含めています。

バケットの作成

try:
  bucket = storage_client.create_bucket(BUCKET_NAME)
except Exception as e:
  print(e)
finally:
  bucket = storage_client.get_bucket(BUCKET_NAME)
  print(f"バケット名: {bucket.name}")

bucketの作成にはcreate_bucketメソッドを使用します。
同名のバケットが既に存在する場合には、リクエストは失費し、ステータスコード409が返されます。

バケットの一覧を取得

buckets = storage_client.list_buckets()
for bucket in buckets:
  print(f"バケット名: {bucket.name}")

空のバケットを削除

bucket = storage_client.get_bucket(BUCKET_NAME)

bucket.delete()

バケット内にオブジェクトがある場合には、リクエストは失敗し、ステータスコード409が返されます。
バケット内のオブジェクトごと削除したい場合は、`bucket.delete(force=True)`のように引数を渡します。

ファイル操作

ファイルのアップロード

bucket = storage_client.create_bucket(BUCKET_NAME)

blob = bucket.blob('cloud_sample.png')
blob.upload_from_filename(filename='sample.png')

blob = bucket.blob('img/cloud_sample.png')
blob.upload_from_filename(filename='sample.png')

GCS上の特定のファイル(ブロブ)とやり取りするためのPythonオブジェクトを準備します。
1つ目のアップロード操作では、local-sample.pngがGCSにcloud_sample.pngとして保存されます。
2つ目のアップロード操作では、GCSにimg/cloud_sample.pngとして保存されます。
コンソール上では、imgフォルダにcloud_sample.pngが格納されているように表現されます。

ファイルアップロード(上書きを避ける)

from google.cloud.exceptions import PreconditionFailed

bucket = storage_client.get_bucket(BUCKET_NAME)
blob = bucket.blob('cloud_sample.png')

try:
  blob.upload_from_filename(filename='sample.png', if_generation_match=0)
except PreconditionFailed  as e:
  print("cloud_sample.pngは既に存在します。")
except Exception as e:
  print(e)

ファイルアップロード時に上書きを避けたい場合にはif_generation_match0を渡します。 世代は常に正の値が設定されるため、既に同名のオブジェクトが存在する場合、リクエストは失敗し、ステータス コード 412 Precondition Failed が返されます。

ファイルダウンロード

bucket = storage_client.get_bucket(BUCKET_NAME)
blob = bucket.blob('cloud_sample.png')

blob.download_to_filename(filename="sample_downloaded.png")

ファイルの一覧を取得

bucket = storage_client.get_bucket(BUCKET_NAME)
blobs = bucket.list_blobs()

for blob in blobs:
  print(f"オブジェクト名: {blob.name}") 

ファイルをコピー

bucket = storage_client.get_bucket(BUCKET_NAME)
blob = bucket.blob('cloud_sample.png')

bucket.copy_blob(blob, bucket, 'cloud_sample_copy.png')

引数にはコピー元のブロブ、コピー先のバケット、コピー先のオブジェクト名を指定してます。

ファイルを削除

blob = bucket.blob('cloud_sample.png')
blob.delete()

blobs = bucket.list_blobs()
for blob in blobs:
  print(f"オブジェクト名: {blob.name}")