Created 2019年1月26日0:06
Updated 2019年1月30日0:34
Categories
Python
Google Photos API
Google Photosにある画像をスクリプトで取得したいと思い、やり方を調べてみました。
昔はPicasa APIみたいなのを使わないといけませんでしたが、Google Photos APIというのができたみたいです。
ただし、Google Photos APIを使うにはOauth2で認証しなければなりません。
GoogleのメジャーなAPIならPythonの公式ライブラリがあるのですが、Photos APIは確認した限り無かったので、自分で認証や取得を行う必要があります。
今回は、Requests-OAuthlibを用いて認証を行ってみました。
JSONの内容はこんな感じです。
{
"installed":{
"client_id":"#####",
"project_id":"#####",
"auth_uri":"#####",
"token_uri":"#####",
...
}
}
ダウンロードしたcredentials.jsonをスクリプトと同じディレクトリに配置してください。
from pathlib import Path
from requests_oauthlib import OAuth2Session
import json
# APIのURLやスコープ
api_url = "https://photoslibrary.googleapis.com/v1/mediaItems"
scope = ["https://www.googleapis.com/auth/photoslibrary.readonly"]
# ログイン後に取得したトークンをtoken.jsonに保存
def save_token(token):
token = {
"access_token": token.get("access_token"),
"refresh_token": token.get("refresh_token"),
"token_type": token.get("token_type"),
"expires_in": token.get("expires_in")
}
Path("token.json").write_text(json.dumps(token))
# token.jsonが存在したら読み込み
def load_token():
# 存在しない場合は期限切れのダミーを返す
token = {
"access_token": "",
"refresh_token": "",
"token_type": "",
"expires_in": "-30",
}
path = Path("token.json")
if path.exists():
token = json.loads(path.read_text())
return token
# ログインしてセッションオブジェクトを返す
def login():
# 認証情報を読み込み
auth_info = json.loads(Path("credentials.json").read_text()).get("installed", None)
assert auth_info is not None
# トークンがあったら読み込む
token = load_token()
# トークン更新用の認証情報
extras = {
"client_id": auth_info.get("client_id"),
"client_secret": auth_info.get("client_secret"),
}
# セッションオブジェクトを作成
google = OAuth2Session(
auth_info.get("client_id"),
scope=scope,
token=token,
auto_refresh_kwargs=extras,
token_updater=save_token,
auto_refresh_url=auth_info.get("token_uri"),
redirect_uri=auth_info.get("redirect_uris")[0]
)
# ログインしていない場合ログインを行う
if not google.authorized:
authorization_url, state = google.authorization_url(
auth_info.get("auth_uri"),
access_type="offline",
prompt="select_account"
)
# 認証URLにアクセスしてコードをペースト
print("Access {} and paste code.".format(authorization_url))
access_code = input(">>> ")
google.fetch_token(
auth_info.get("token_uri"),
client_secret=auth_info.get("client_secret"),
code=access_code
)
assert google.authorized
# トークンを保存(本来自動保存なのだが、なぜか動かないので追加)
save_token(google.token)
return google
def test():
google = login()
# Photosのコンテンツを取得
response = google.get(api_url)
print(response.text)
if __name__ == "__main__":
test()
実行するとURLが表示されますので、ブラウザでアクセスして表示されたコードを入力してください。
その後、Google Photosのメディア一覧が表示されると思います。
なお、実行後はトークンが平文でtoken.jsonとして保存されます。扱いには注意してください。
参考になりました。ありがとうございます。