エラー内容
Google Compute Engine(GCE)インスタンスから、google-cloud-storageを利用して、Google Cloud Storage(GCS)へファイルアップロードを実行。
post_gcs.py
from google.cloud import storage
import os
os.environ["GOOGLE_APPLICATION_CREDIENTIALS"] = 'CREDIENTILS.json'
client = storage.Client("PROJECT_ID")
bucket = client.get_bucket("BUCKET_NAME")
blob = bucket.blob("CSV_FILE")
blob.upload_from_filename(filename="FILE_NAME")
しかし、以下のエラーが返ってきてアップロードが成功しない。
Traceback (most recent call last):
File "getjson.py", line 108, in <module>
get_audio_features(sp, search_word)
File "getjson.py", line 86, in get_audio_features
blob.upload_from_filename(filename='df-audio-features/audio_features_{}.csv'.format(search_word))
File "/root/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 1140, in upload_from_filename
predefined_acl=predefined_acl,
File "/root/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 1089, in upload_from_file
_raise_from_invalid_response(exc)
File "/root/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 1960, in _raise_from_invalid_response
raise exceptions.from_http_status(response.status_code, message, response=response)
google.api_core.exceptions.Forbidden: 403 POST https://www.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=multipart: ('Request failed with status code', 403, 'Expected one of', <HTTPStatus.OK: 200>)
原因
調べたところ、インスタンスはデフォルトのスコープが、ストレージ(GCS)に関して「読み取り」のみになっている様子。
解決
以下のコマンドにより、該当のインスタンスにGCSへの書き込みのスコープを付与する。
gcloud beta compute instances set-scopes projects/プロジェクトID/zones/利用ゾーン名/instances/インスタンス名 --service-account サービスアカウント --scopes https://www.googleapis.com/auth/devstorage.read_write
- 参考:https://qiita.com/Sekky0905/items/e1ae602a1a2a4edb17df
- アカウントIDはインスタンスのページから確認可能です。
エラー文によると、スコープの変更を実行する際には、インスタンスを停止する必要があるとのこと。インスタンスを停止した状態で実行したら、コマンドが通りました。
その後、上記したpythonコードにてGCSへのファイルアップロードが成功しました。