pythongoogle-oauthgoogle-api-python-clientgoogle-photos-api

Google Photos API + python: Working non-deprecated example


I've been finding such a mix of code examples. But nothing with a maintained library (google-auth) + full working example. google-api-python-client and oauth2client are no longer supported (https://github.com/googleapis/google-api-python-client/issues/651).

Here's a working example with deprecated libraries, but I'd like to see some examples that allow full access to the api (searching by albumId currently doesn't work with this library):

from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

# Setup the Photo v1 API
SCOPES = 'https://www.googleapis.com/auth/photoslibrary.readonly'
store = file.Storage('credentials.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
    creds = tools.run_flow(flow, store)
service = build('photoslibrary', 'v1', http=creds.authorize(Http()))

# Call the Photo v1 API
results = service.albums().list(
    pageSize=10, fields="nextPageToken,albums(id,title)").execute()
items = results.get('albums', [])
if not items:
    print('No albums found.')
else:
    print('Albums:')
    for item in items:
        print('{0} ({1})'.format(item['title'].encode('utf8'), item['id']))

Solution

  • If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

    For example, the sample script for authorizing can be seen at the Quickstart of Drive API with python. You can see the method for installing the library. Using this, your script can be modified as follows.

    Modified script:

    from __future__ import print_function
    import pickle
    import os.path
    from googleapiclient.discovery import build
    from google_auth_oauthlib.flow import InstalledAppFlow
    from google.auth.transport.requests import Request
    
    
    def main():
        credentialsFile = 'credentials.json'  # Please set the filename of credentials.json
        pickleFile = 'token.pickle'  # Please set the filename of pickle file.
    
        SCOPES = ['https://www.googleapis.com/auth/photoslibrary']
        creds = None
        if os.path.exists(pickleFile):
            with open(pickleFile, 'rb') as token:
                creds = pickle.load(token)
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    credentialsFile, SCOPES)
                creds = flow.run_local_server()
            with open(pickleFile, 'wb') as token:
                pickle.dump(creds, token)
    
        service = build('photoslibrary', 'v1', credentials=creds)
    
        # Call the Photo v1 API
        results = service.albums().list(
            pageSize=10, fields="nextPageToken,albums(id,title)").execute()
        items = results.get('albums', [])
        if not items:
            print('No albums found.')
        else:
            print('Albums:')
            for item in items:
                print('{0} ({1})'.format(item['title'].encode('utf8'), item['id']))
    
    
    if __name__ == '__main__':
        main()
    

    References:

    If I misunderstood your question and this was not the direction you want, I apologize.

    Added 1:

    If you want to use the method of mediaItems.search, how about the following sample script? About the script for authorizing, please use above script.

    Sample script:

    service = build('photoslibrary', 'v1', credentials=creds)
    albumId = '###'  # Please set the album ID.
    results = service.mediaItems().search(body={'albumId': albumId}).execute()
    print(results)
    

    Added 2:

    If my understanding is correct, how about this sample script?

    Sample script:

    Before you use this script, please set the variable of albumId.

    from __future__ import print_function
    import json
    import pickle
    import os.path
    import requests
    from google_auth_oauthlib.flow import InstalledAppFlow
    from google.auth.transport.requests import Request
    
    
    def main():
        credentialsFile = 'credentials.json'
        pickleFile = 'token.pickle'
    
        SCOPES = ['https://www.googleapis.com/auth/photoslibrary.readonly']
        creds = None
        if os.path.exists(pickleFile):
            with open(pickleFile, 'rb') as token:
                creds = pickle.load(token)
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    credentialsFile, SCOPES)
                creds = flow.run_local_server()
            with open(pickleFile, 'wb') as token:
                pickle.dump(creds, token)
    
        albumId = '###'  # <--- Please set the album ID.
    
        url = 'https://photoslibrary.googleapis.com/v1/mediaItems:search'
        payload = {'albumId': albumId}
        headers = {
            'content-type': 'application/json',
            'Authorization': 'Bearer ' + creds.token
        }
        res = requests.post(url, data=json.dumps(payload), headers=headers)
        print(res.text)
    
    
    if __name__ == '__main__':
        main()
    

    Note:

    Reference: