はじめに
BytesIOとは
BytesIOとは、メモリ上でバイナリデータを扱うための機能であり、Python の標準ライブラリ io に含まれています。バイナリデータとは主に画像や音声などのデータのことを示しています。(C#でいうMemoryStreamのようなものです)
サービスアカウントの作成
Google Cloud Platformにアクセスしてサービスアカウントの作成(API)を行います。
ナビゲーションメニュー > APIとサービス > 認証情報 をクリックし画面に移動します。
そしてサービスアカウントを管理をクリックします。
次の画面ではサービスアカウントを作成をクリックします。
サービスアカウントの詳細を各項目入力していきます。
設定項目 | 設定内容 |
---|---|
サービス アカウント名 | (任意の名前に設定) |
サービスアカウント説明 | (各プロジェクトわかりやすいように任意で設定) |
入力が終了したら作成をクリックします。 | |
次の項目ではCloud Storageに関するロールを作ります。今回はテストなのでストレージ管理者 (フル権限)を選択しました。 |
|
使用アプリケーションに応じてロールを変更するようにしましょう。 | |
最後の項目は省略して大丈夫です。
作成したサービスアカウントをクリックし、キーの項目で鍵を追加をクリックし新しい鍵を作成を選択します。
キーのタイプはJSONを選択して「作成」します。ローカルストレージ内にJSONファイルがダウンロードされるので次の項目でそのJSONファイルを使用し、PythonからCloud Storageを操作していきます。
PythonからCloudStorageを操作
Pythonライブラリーのインストール
今回のプロジェクトで必要なライブラリーを順番にインストールしていきます。
まずCloud Storageにアクセスするために、pip install で Google Cloud Storage のライブラリーをインストールを行います。
pip install google-cloud-storage
BytesIOを経由して Pillowを使いローカル上にファイルに保存するためPillowもインストールしていきます。
pip install requests pillow
Excelファイルなども試したい方向け、openpyxlのインストール
pip install openpyxl
Cloud Storage上のバケットの準備
GUIからGoogle Cloud Storageにアクセスし、バケットを作成し適当な画像ファイルを準備します。
コンソール画面から ナビゲーションメニュー > Cloud Storage で移動します。
今回はPythonのロゴファイルをダウンロードし、image.pngという名前をつけ保存しました。
Pythonのロゴファイル
PythonからCloud Storageにアクセスし画像を取得
最初の方で作成したアクセスユーザのキーを使いCloud Storageにアクセスをしていきます。
まず最初にアクセスユーザのキーを読み込ませる必要があります。2通りのアクセスの参照の仕方を記載します。
# 環境変数を使用しアクセスする場合
import os
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = '{jsonファイルが置かれているパスを記入}'
client= storage.Client()
# 直にjsonファイルへアクセスする場合。
client = storage.Client.from_service_account_json('{jsonファイルが置かれているパスを記入}')
Google Cloud Storage(GCS)に保存した画像ファイルを取得し、ローカル上にファイルを保存するPythonのコードになります。
プログラムがやっている説明として、ファイルを保存したいbucketと保存ファイル名のblobインスタンスを取得します。
画像のバイナリデータが入っているのでBytesIOを経由してPillowで読み込み、任意の画像ファイルをして書き込む流れになります。
blob.download_to_filename
を使うことによってファイルをGCSから直接ダウンロードしたりすることもできますが、今回はGCSから落としたファイルに対して編集などを加えたりする想定でPILライブラリーなどにデータを渡す形にしています。
from google.cloud import storage
from PIL import Image
import io
#google cloud storageのクライアントインスタンスを作成
#client = storage.Client()
client = storage.Client.from_service_account_json('●●●●●●●●●●.json')
#バケットのインスタンスを取得
bucket = client.bucket('{任意の名前で作成したバケット名}')
#ファイルのblobインスタンスを取得
blob = bucket.blob('image.png')
img = Image.open(io.BytesIO(blob.download_as_string()))
img.save('sample.png')
PythonからCloud Storageにアクセスしエクセルファイルを取得
GCS上のエクセルファイルを取得しそのBlobデータをBytesIOを経由してopenpyxlで読み込み保存します。
blob.download_to_filename
を使うことによってファイルをGCSから直接ダウンロードしたりすることもできますが、今回はGCSから落としたファイルに対して編集などを加えたりする想定でPILライブラリーなどにデータを渡す形にしています。
from google.cloud import storage
import openpyxl
import io
#google cloud storageのクライアントインスタンスを作成
client = storage.Client.from_service_account_json('●●●●●●●●●●.json')
#バケットのインスタンスを取得
bucket = client.bucket('{任意の名前で作成したバケット名}')
##ファイルのblobインスタンスを取得
blob = bucket.blob('test.xlsx')
buffer = io.BytesIO()
blob.download_to_file(buffer)
wb = openpyxl.load_workbook(buffer)
wb.save('./retest.xlsx')
参考にさせていただいた記事
・Cloud Storageの画像をリサイズして再アップロードする - Qiita
・【Python】 バイナリデータの画像を扱う | かずさプログラマーの雑記帳
・Python で Google Cloud Storage と、BigQuery を使う過程でのエラー | Monotalk
・Python - GCP Cloud Functions(Python)でCloud Storage上のExcelファイルを編集したい|teratail
・PythonでOpenPyXLを使ってExcelファイルの新規作成・保存を行う方法
・BytesIO(およびStringIO、cStringIO)の使い方【初心者向け】 | TechAcademyマガジン
・Pythonでオンメモリストリームを利用して、中間データを保存せずファイルを扱う | hgrs's Blog
・pythonでGoogle Cloud Storageへアクセスしてファイルをアップロード/ダウンロードする方法|ドドテクノ
・【Python】 バイナリデータの画像を扱う | かずさプログラマーの雑記帳