PythonからGooglePhotoに画像や動画をアップロードする手順です。
事前準備
Photo Library APIの有効化
はじめにGoogle PhotoのAPIを利用するために「Photo Library API」を有効化する。まず下記のURLからGCPのコンソールにアクセスする。
検索窓で「Google Photo」と入力し、画像赤枠の「Photo Library API」を選択する。
Photo Library APIの設定画面に遷移するので、「有効にする」を押下する。
実行後、下記のような画面に変わればAPIの有効化は完了。GooglePhotoに対してAPI経由で処理を実行できるようになっている。
認証情報の作成
次にAPIの実行するために必要な、認証情報を作成する。認証情報の作成手順は下記の記事の手順と同じなので、こちらを参照。
作成した認証情報はclient_secrets.json
の名称で保存しておく。
開発
必要ライブラリのインストール
今回はPhotoAPIを利用するためのgoogle-api-python-client
と認証に利用するgoogle-auth-oauthlib
をインストールする。
下記のコマンドを実行し、ライブラリのインストールを行う。
pip install google-api-python-client google-auth-oauthlib
実装
import pickle
from pathlib import Path
import requests
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
# 各URLやスコープ
API_SERVICE_NAME = "photoslibrary"
API_VERSION = "v1"
SCOPES = ["https://www.googleapis.com/auth/photoslibrary.appendonly"]
class GooglePhotoFacade:
# ログインしてセッションオブジェクトを返す
def __init__(
self,
credential_path: str,
token_path: str = "",
):
with build(
API_SERVICE_NAME,
API_VERSION,
credentials=self._login(credential_path, token_path),
static_discovery=False,
) as service:
self.service = service
print("Google OAuth is Complete.")
self.credential_path = credential_path
self.token_path = token_path
def _login(self, credential_path: str, token_path: str) -> any:
"""Googleの認証を行う
Args:
credential_path (str): GCPから取得したclient_secret.jsonのパス
token_path (str): Oauth2認証によって得られたトークンを保存するパス。
Returns:
googleapiclient.discovery.Resource: _description_
"""
if Path(token_path).exists():
# TOKENファイルを読み込み
with open(token_path, "rb") as token:
credential = pickle.load(token)
if credential.valid:
print("トークンが有効です.")
return credential
if credential and credential.expired and credential.refresh_token:
print("トークンの期限切れのため、リフレッシュします.")
# TOKENをリフレッシュ
credential.refresh(Request())
else:
print("トークンが存在しないため、作成します.")
credential = InstalledAppFlow.from_client_secrets_file(
credential_path, SCOPES
).run_local_server()
# CredentialをTOKENファイルとして保存
with open(token_path, "wb") as token:
pickle.dump(credential, token)
return credential
def upload(
self, local_file_path: str,
):
self._login(self.credential_path, self.token_path) # トークンの期限を確認
save_file_name:str = Path(local_file_path).name
with open(str(local_file_path), "rb") as image_data:
url = "https://photoslibrary.googleapis.com/v1/uploads"
headers = {
"Authorization": "Bearer " + self.service._http.credentials.token,
"Content-Type": "application/octet-stream",
"X-Goog-Upload-File-Name": save_file_name.encode(),
"X-Goog-Upload-Protocol": "raw",
}
response = requests.post(url, data=image_data.raw, headers=headers)
upload_token = response.content.decode("utf-8")
print("Google Photoへのアップロードが完了しました。")
body = {"newMediaItems": [{"simpleMediaItem": {"uploadToken": upload_token}}]}
upload_response = self.service.mediaItems().batchCreate(body=body).execute()
print("Google Photoへのアップロードした動画の登録に成功しました。")
# uploadしたURLを返す
return upload_response["newMediaItemResults"][0]["mediaItem"]
if __name__ == "__main__":
g = GooglePhotoFacade(
credential_path="client_secret.json", token_path="token.pkl"
)
g.upload(
local_file_path="qiitan.png", # ここに保存する画像を指定する。
)
動作確認
動作確認として、下記のQiitanの画像をアップロードしてみる。
$ python main.py
トークンが存在しないため、作成します.
Please visit this URL to authorize this application: ${省略}
Google OAuth is Complete.
Google Photoへのアップロードが完了しました。
Google Photoへのアップロードした動画の登録に成功しました。
初回実行時はOAuth2の認証画面が表示される。はじめに、アップロードしたいGooglePhotoのアカウントを選択する。
下記の画面に遷移されるので「続行」を押下する。
その後下記の画面へ遷移するので、再度「続行」を押下する。
その後、トークンがtoken.pkl
の名称でローカル保存される。2回目以降はローカルに保存したトークンを利用するので認証画面なしで実行ができる。
実行後、Google Photoにアクセスし、Qiitanの画像がアップロードされていることを確認する。
同じソースコードで動画もアップロードが可能である。local_file_path
にmp4形式の動画を指定する。
~~~省略~~~
if __name__ == "__main__":
g = GooglePhotoFacade(
credential_path="client_secret.json", token_path="token.pkl"
)
g.upload(
local_file_path="sample.mp4", # 動画を指定する
)
再度下記のコマンドでアップロード処理を実行する。
python main.py
動画がアップロードされたことが確認できる。