Help us understand the problem. What is going on with this article?

[GoogleCloudStorage] GCSのPythonAPIの使い方 [備忘]

1行で

  • GCSのPythonAPI(google-cloud-storage)のよく使う処理をベタ書き&ラッパー関数としてここに作っておく

GCSをPythonで使うたびに公式ページでいろいろ調べに行っているのがあまりに効率悪いのですぐコピペできるようにQiitaに書いておく

認証通す

pip install goole-cloud-storageで事前にライブラリ自体はインストールしておく

また、以下の前提で話を進める

  • Python>=3.5
  • google-cloud-storage==1.23.0

GoogleCloudPlatform上で実行

GCP上ならば別にクレデンシャル情報は不要

from google.cloud import storage as gcs

project_id = "{ProjectName}"
client = gcs.Client(project_id)

ローカルで実行

ローカルで実行するにはサービスアカウントのjsonファイルを手元に用意してパスを通しておく必要あり

やり方は公式を参照

from google.cloud import storage as gcs
from google.oauth2 import service_account

key_path = '{クレデンシャルを格納しているPath}'
credential = service_account.Credentials.from_service_account_file(key_path)

project_id = "{ProjectName}"
client = gcs.Client(project_id, credentials=credential)

バケット一覧を表示する

Projectに存在するバケットがどんなものかを確認する

バケットの一覧を表示
project_id = "{ProjectName}"
client = gcs.Client(project_id, credentials=credential)

[print(bucket.name) for bucket in client.list_buckets()]

ちなみにバケットは名称を指定してオブジェクトを取得できる

バケットのオブジェクトを取得する
project_id = "{ProjectName}"
bucket_name = "{BucketName}"

client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)

ローカルファイルをUpload

ローカルにあるファイルをGCSの特定のパスにUploadする

ファイルとしてUpload

まずは、普通にファイルをGCSにUploadするパターン

ローカルファイルのパスを指定してGCSに格納
project_id = "{ProjectName}"
bucket_name = "{BucketName}"
gcs_path = "{GCSFilePath}"
local_path = "{LocalFilePath}"

client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)
# 格納するGCSのPathを指定(/xxx/yyy.csv)的な
blob_gcs = bucket.blob(gcs_path)
# ローカルのファイルパスを指定
blob_gcs.upload_from_filename(local_path)

pd.DataFrameとしてUpload

たまに面倒くさくなっていきなりDataFrameからCSVにシリアライズしてGCSに格納したくなるので書いておく

DataFrameをいきなりGCSに入れちゃう
import pandas as pd

project_id = "{ProjectName}"
bucket_name = "{BucketName}"
gcs_path = "{GCSFilePath}"

client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)

# 格納するGCSパスを指定
blob = bucket.blob(gcs_path)

df = pd.DataFrame([[1,2,3],[5,6,7]],columns=["x","y","z"])
# DataFrameをGCSにUpload(ヘッダーは入れるが、インデックスは落とす)
blob.upload_from_string(df.to_csv(index=flg_index, header=flg_header, sep=","))

GCSのファイルをDownload

次にDownloadするパターン
ファイルとして落としてくる場合とDataFrameとして落としてくる場合をカバーしておく

ファイルとしてDownload

まずはファイルとしてDownloadする場合

GCSにあるファイルをローカルに落としてくる
project_id = "{ProjectName}"
bucket_name = "{BucketName}"
gcs_path = "{GCSFilePath}"
local_path = "{LocalPath}"

client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)

# GCSにあるダウンロードしたいファイルを指定
blob = bucket.blob(gcs_path)
# ファイルとしてローカルに落とす
blob.download_to_filename(local_path)

CSVをDataFrameとして受け取る

変則的だが、CSVファイルを直接pd.DataFrameとして受け取るパターンもよく使うから書いておく

GCSにあるファイルをDataFrameとして受け取る
import pandas as pd

from io import BytesIO

project_id = "{ProjectName}"
bucket_name = "{BucketName}"
gcs_path = "{GCSFilePath}"

client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)

# GCSにあるダウンロードしたいファイルを指定
blob = bucket.blob(gcs_path)
# DataFrameとして受け取る(ヘッダーありのCSVを想定)
df = pd.read_csv(BytesIO(blob.download_as_string()))
df.head()

バケット内のファイル一覧を取得する

バケットにあるファイルの中身を確認することもそれなりにあるので、これも記載しておく

バケットを指定してファイル一覧を表示
project_id = "{ProjectName}"
bucket_name = "{BucketName}"
client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)

[print(file.name) for file in client.list_blobs(bucket_name)]

機能をクラスでまとめておく

ここまで書いた内容をいちいちコピペするのが面倒なのでクラスにしてまとめておく

ラッパークラスを定義
import pandas as pd

from google.cloud import storage as gcs
from io import BytesIO


class GCSWrapper:
    def __init__(self, project_id, bucket_id):
        """GCSのラッパークラス
        Arguments:
            project_id {str} -- GoogleCloudPlatform Project ID
            bucket_id {str} -- GoogleCloudStorage Bucket ID
        """
        self._project_id = project_id
        self._bucket_id = bucket_id
        self._client = gcs.Client(project_id)
        self._bucket = self._client.get_bucket(self._bucket_id)

    def show_bucket_names(self):
        """バケット名の一覧を表示
        """
        [print(bucket.name) for bucket in self._client.list_buckets()]

    def show_file_names(self):
        """バケット内のファイル一覧を表示
        """
        [print(file.name) for file in self._client.list_blobs(self._bucket)]

    def upload_file(self, local_path, gcs_path):
        """GCSにローカルファイルをアップロード

        Arguments:
            local_path {str} -- local file path
            gcs_path {str} -- gcs file path
        """
        blob = self._bucket.blob(gcs_path)
        blob.upload_from_filename(local_path)

    def upload_file_as_dataframe(self, df, gcs_path, flg_index=False, flg_header=True):
        """GCSにpd.DataFrameをCSVとしてアップロード

        Arguments:
            df {pd.DataFrame} -- DataFrame for upload
            gcs_path {str} -- gcs file path

        Keyword Arguments:
            flg_index {bool} -- DataFrame index flg (default: {False})
            flg_header {bool} -- DataFrame header flg (default: {True})
        """
        blob = self._bucket.blob(gcs_path)
        blob.upload_from_string(df.to_csv(
            index=flg_index, header=flg_header, sep=","))

    def download_file(self, local_path, gcs_path):
        """GCSのファイルをファイルとしてダウンロード

        Arguments:
            local_path {str} -- local file path
            gcs_path {str} -- gcs file path
        """
        blob = self._bucket.blob(gcs_path)
        blob.download_to_filename(local_path)

    def download_file_as_dataframe(self, gcs_csv_path):
        """GCSのファイルをpd.DataFrameとしてダウンロード

        Arguments:
            gcs_csv_path {str} -- gcs file path (only csv file)

        Returns:
            [pd.DataFrame] -- csv data as pd.DataFrame
        """
        blob = self._bucket.blob(gcs_csv_path)
        content = blob.download_as_string()
        df = pd.read_csv(BytesIO(content))
        return df

おしまい

参考

【GoogleCloudPlatform】pythonでGCSバケットのデータを読み出す/書き出す

API Reference

brainpad
ブレインパッドは、2004年の創業以来、データによるビジネス創造と経営改善に向き合ってきたデータ活用・分析企業です。
http://www.brainpad.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした