TL;DR
PythonからGCPへ接続する際の認証情報の設定方法が、サービスアカウントのJSONファイルのパスを指定する方法しか見つからなかった。
Gitには認証JSONを乗せたくないし、本番運用時にサーバーにアップロードするのも面倒なので楽に設定できる方法がないか調査した結果をまとめました。
1. GCPからJSONファイルをダウンロード
詳しくは割愛。中身はこんな感じ。
credential.json
{
"type": "service_account",
"project_id": "***************",
"private_key_id": "***************",
"private_key": "-----BEGIN PRIVATE KEY-----************-----END PRIVATE KEY-----\n",
"client_email": "***************@***************.iam.gserviceaccount.com",
"client_id": "***************",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "***************"
}
2. ライブラリをインストール
pip install google-cloud-storage python-dotenv
google-cloud-storage
今回は、GCSへ接続するためのライブラリで認証情報を設定していきます。
python-dotenv
環境変数を.env
から読み込むために使用します。
3. .env
に環境変数を設定
先ほどダウンロードしたJSONファイルの中身をコピペします。
GCP_PROJECT_ID=********
GCS_PRIVATE_KEY_ID=********
GCS_PRIVATE_KEY=********
GCS_CLIENT_MAIL=********
GCS_CLIENT_ID=********
GCS_CLIENT_X509_CERT_URL=********
4. 環境変数を読み込み
settings.py
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
5. Clientクラスを作成
GCS_PRIVATE_KEY
には改行コード\n
が含まれているのですが、環境変数経由で読み込むとエスケープされてしまうので、replace
で元に戻してあげます。
client.py
import os
from google.oauth2.service_account import Credentials
from google.cloud import storage
class GoogleCloudStorageClient:
cred = Credentials.from_service_account_info({
"type": "service_account",
"project_id": os.environ["GCP_PROJECT_ID"],
"private_key_id": os.environ["GCS_PRIVATE_KEY_ID"],
"private_key": os.environ["GCS_PRIVATE_KEY"].replace("\\n", "\n"),
"client_email": os.environ["GCS_CLIENT_MAIL"],
"client_id": os.environ["GCS_CLIENT_ID"],
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": os.environ["GCS_CLIENT_X509_CERT_URL"]
})
client = storage.Client(credentials=cred)
@classmethod
def _create_bucket_instance(cls,
bucket_name: str,
destination_blob_name: str):
bucket = cls.client.bucket(bucket_name)
return bucket.blob(destination_blob_name)
@classmethod
def upload_file(cls,
bucket_name: str,
destination_blob_name: str,
local_file_path: str) -> None:
blob = cls._create_bucket_instance(bucket_name, destination_blob_name)
blob.upload_from_filename(local_file_path)
storage.Client()
credentials
に何も設定していない場合は環境変数に認証JSONファイルパスを設定しないといけません。
今回はJSONファイルが無くても認証が通るように、ライブラリで用意されている認証情報オブジェクトを生成して渡しています。
6. 呼び出し
main.py
bucket_name = "XXX" # 保存先のバケット名
destination_blob_name = "YYY/ZZZ.csv" # 保存先となるバケット内でのファイルパス
local_file_path = "LOCAL/FILE.csv" # 保存したいファイルパス
GoogleCloudStorageClient.upload_file(
bucket_name,
destination_blob_name,
local_file_path
)