2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonでGoogle Photos APIを使う

Posted at

![HW Raspberry Pi 4 Model B Rev 1.4](https://img.shields.io/badge/HW-Raspberry Pi 4 Model B Rev 1.4-brightgreen) ![OS-Ubuntu 20.04.1 LTS](https://img.shields.io/badge/OS-Ubuntu 20.04.1 LTS-brightgreen) Python-3.8.7

はじめに

PythonでGoogle Photos APIを叩こうと思ってネットを調べていたところ、google-api-python-clientのバージョンが2になっていたため上手く動かずに時間を使ってしまったので、記事投稿時点で動くコードを上げておく。
事前にGoogle Photos APIを有効化し、OAuth 2.0 Clientを作成してclient_secret.jsonを取得しておく必要がありますが、ここでは割愛します。

エラー

下記のようなコードでphotoslibraryを叩こうとすると、
buildのところでコケる。

sample.py
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/photoslibrary"]
API_SERVICE_NAME = "photoslibrary"
API_VERSION = 'v1'
CLIENT_SECRET_FILE = './secret/client_secret.json'

creds = InstalledAppFlow.from_client_secrets_file(
            CLIENT_SECRET_FILE, SCOPES).run_local_server()

with build(API_SERVICE_NAME, API_VERSION, credentials=creds) as service:
    print(service.albums().list(pageSize=50).execute())

何やらこんなAPIは知らんと怒られた。
Google Photos Libraryはgoogle-api-python-clientで定義されていないようだ。

googleapiclient.errors.UnknownApiNameOrVersion: name: photoslibrary  version: v1

結論

version 2.0.0以降は、指定しない場合デフォルトでライブラリ内を見るように変更されていた。GooglePhotosLibraryはローカルでは見つからないので、インターネット経由でDiscoveryかけるようにbuild時にstatic_discovery=Falseを指定してあげればよい。

下記はGoogle Photos APIを叩いてアルバムのリストを取得して表示するサンプル。

sample.py
import pickle
from pathlib import Path

from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/photoslibrary"]
API_SERVICE_NAME = "photoslibrary"
API_VERSION = 'v1'
CLIENT_SECRET_FILE = './secret/client_secret.json'
TOKEN_PICKLE = "./secret/token.pickle"

def get_authenticated_service() -> object:
    if Path(TOKEN_PICKLE).exists():
        # TOKENファイルを読み込み
        with open(TOKEN_PICKLE, "rb") as token:
            creds = pickle.load(token)
        if creds.valid:
            return creds
        if creds and creds.expired and creds.refresh_token:
            # TOKENをリフレッシュ
            creds.refresh(Request())
    else:
        # TOKENファイルがないので認証フローを起動する(Default: host=localhost, port=8080)
        creds = InstalledAppFlow.from_client_secrets_file(
                    CLIENT_SECRET_FILE, SCOPES).run_local_server()

    # CredentialをTOKENファイルとして保存
    with open(TOKEN_PICKLE, 'wb') as token:
        pickle.dump(creds, token)

    return creds

def main():
    with build(API_SERVICE_NAME, API_VERSION, credentials=get_authenticated_service(), static_discovery=False) as service:
        print(service.albums().list(pageSize=50).execute())

if __name__ == "__main__":
    main()

google-api-python-clientのv1系とv2系の違い

MigrationGuideにBraking Changeとして明記されている。
下記は該当箇所の抜粋

v1系

from googleapiclient.discovery import build

# Retrieve discovery artifacts from the internet
with build('drive', 'v3') as service:

v2系

from googleapiclient.discovery import build

# Retrieve discovery artifacts from the client library
with build('drive', 'v3') as service:
    # ...

# Retrieve discovery artifacts from the internet
with build('drive', 'v3', static_discovery=False) as service:
    # ...

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?